home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-18 | 408.3 KB | 13,301 lines |
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/README samba-1.9.16alpha11/README
- --- samba-1.9.16alpha10/README Tue May 28 23:37:21 1996
- +++ samba-1.9.16alpha11/README Sun Jun 30 15:17:17 1996
- @@ -10,21 +10,27 @@
- WHAT CAN SAMBA DO?
- ==================
-
- -Here is a very short list of what samba includes, and what it does
- +Here is a very short list of what samba includes, and what it does.
-
- -- a SMB server, to provide LanManager style file and print services to PCs
- +- a SMB server, to provide Windows NT and LAN Manager-style file and print
- + services to SMB clients such as Windows 95, Warp Server, smbfs and others.
-
- -- a Netbios (rfc1001/1002) nameserver
- +- a Netbios (rfc1001/1002) nameserver, which among other things gives
- + browsing support. Samba can be the master browser on your LAN if you wish.
-
- - a ftp-like SMB client so you can access PC resources (disks and
- -printers) from unix
- +printers) from unix, Netware and other operating systems
-
- - a tar extension to the client for backing up PCs
-
- +For a much better overview have a look at the web site at
- +http://samba.canberra.edu.au/pub/samba, and browse the user survey.
- +
- Related packages include:
-
- -- ksmbfs, a linux-only filesystem allowing you to mount remote SMB
- -filesystems from PCs on your linux box
- +- smbfs, a linux-only filesystem allowing you to mount remote SMB
- +filesystems from PCs on your linux box. This is included as standard with
- +Linux 2.0 and later.
-
- - tcpdump-smb, a extension to tcpdump to allow you to investigate SMB
- networking problems over netbeui and tcp/ip
- @@ -47,7 +53,8 @@
-
- Remember that free software of this kind lives or dies by the response
- we get. If noone tells us they like it then we'll probably move onto
- -something else.
- +something else. However, as you can see from the user survey quite a lot of
- +people do seem to like it at the moment :-)
-
- Andrew Tridgell
- Email: samba-bugs@samba.anu.edu.au
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/docs/announce samba-1.9.16alpha11/docs/announce
- --- samba-1.9.16alpha10/docs/announce Tue May 28 23:37:23 1996
- +++ samba-1.9.16alpha11/docs/announce Sun Jun 30 15:17:19 1996
- @@ -4,19 +4,21 @@
- What is Samba?
- --------------
-
- -Samba is a Unix based SMB file server. This allows a Unix host to
- -act as a file and print server for SMB clients. This includes
- +Samba is a SMB file server that runs on Unix and other operating systems.
- +It allows these operating systems (currently Unix, Netware, OS/2 and
- +AmigaDOS) to act as a file and print server for SMB clients. There are many
- Lan-Manager compatible clients such as LanManager for DOS, Windows for
- Workgroups, Windows NT, Windows 95, OS/2, Pathworks and many more.
-
- -The package also includes a Unix SMB client and a netbios nameserver.
- +The package also includes a SMB client for accessing other SMB servers
- +and a netbios nameserver for browsing support.
-
- What can it do for me?
- ----------------------
-
- If you have any PCs running SMB clients, such as a PC running Windows
- -for Workgroups, then you can mount file space or printers from a unix
- -host, so that directories, files and printers on the unix host are
- +for Workgroups, then you can mount file space or printers on a Samba
- +host, so that directories, files and printers on the host are
- available on the PC.
-
- The client part of the package will also allow you to attach to other
- @@ -31,7 +33,7 @@
-
- Samba supports many features that are not supported in other SMB
- implementations (all of which are commercial). Some of it's features
- -include host as well as username/password security, a unix client,
- +include host as well as username/password security, a client,
- automatic home directory exporting, automatic printer exporting, dead
- connection timeouts, umask support, guest connections, name mangling
- and hidden and system attribute mapping. Look at the man pages
- @@ -66,7 +68,7 @@
- GNU Public licence in source code form at no cost. Please read the
- file COPYING that comes with the package for more information.
-
- -What flavours of unix does it support?
- +What operating systems does it support?
- ---------------------------------------
-
- The code has been written to be as portable as possible. It has been
- @@ -79,7 +81,9 @@
- Domain/OS and DGUX.
-
- Some of these have received more testing than others. If it doesn't
- -work with your unix then it should be easy to fix.
- +work with your unix then it should be easy to fix. It has also been ported
- +to Netware, OS/2 and the Amiga. A VMS port is underway. See the web site
- +for more details.
-
- Who wrote it?
- -------------
- @@ -125,5 +129,5 @@
- A WWW site with lots of Samba info can be found at
- http://samba.canberra.edu.au/pub/samba/
-
- -Andrew Tridgell (Contact: samba-bugs@anu.edu.au)
- -January 1995
- +The Samba Team (Contact: samba-bugs@anu.edu.au)
- +June 1996
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/docs/security_level.txt samba-1.9.16alpha11/docs/security_level.txt
- --- samba-1.9.16alpha10/docs/security_level.txt Thu May 30 10:05:51 1996
- +++ samba-1.9.16alpha11/docs/security_level.txt Sun Jun 30 15:17:19 1996
- @@ -42,14 +42,14 @@
- operation. The client is expecting a password to be associated with
- each share, independent of the user. This means that samba has to work
- out what username the client probably wants to use. It is never
- -explicitly sent the username. A "real" SMB server like NT actually
- -associates passwords directly with shares in share level security, but
- +explicitly sent the username. Some commercial SMB servers such as NT actually
- +associate passwords directly with shares in share level security, but
- samba always uses the unix authentication scheme where it is a
- username/password that is authenticated, not a "share/password".
-
- Many clients send a "session setup" even if the server is in share
- level security. They normally send a valid username but no
- -password. Samba records this username is a list of "possible
- +password. Samba records this username in a list of "possible
- usernames". When the client then does a "tree connection" it also adds
- to this list the name of the share they try to connect to (useful for
- home directories) and any users listed in the "user =" smb.conf
- @@ -75,4 +75,5 @@
- enabled to support this feature, and you have to maintain a separate
- smbpasswd file with SMB style encrypted passwords. It is
- cryptographically impossible to translate from unix style encryption
- -to SMB style encryption.
- +to SMB style encryption, although there are some fairly simple management
- +schemes by which the two could be kept in sync.
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/examples/simple/smb.conf samba-1.9.16alpha11/examples/simple/smb.conf
- --- samba-1.9.16alpha10/examples/simple/smb.conf Sat May 4 17:50:25 1996
- +++ samba-1.9.16alpha11/examples/simple/smb.conf Mon Jul 15 17:54:57 1996
- @@ -80,11 +80,13 @@
- writable = no
- create mode = 0700
-
- -; you might also want this one
- +; you might also want this one, notice that it is read only so as not to give
- +; people without an account write access.
- +;
- ; [tmp]
- ; comment = Temporary file space
- ; path = /tmp
- -; read only = no
- +; read only = yes
- ; public = yes
-
- ;
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/Makefile samba-1.9.16alpha11/source/Makefile
- --- samba-1.9.16alpha10/source/Makefile Mon Jun 10 15:18:47 1996
- +++ samba-1.9.16alpha11/source/Makefile Thu Jul 18 20:53:13 1996
- @@ -1,6 +1,6 @@
- ###########################################################################
- # Makefile for Samba SMB client/server for unix
- -# Copyright Andrew Tridgell 1992,1993,1994
- +# Copyright Andrew Tridgell 1992-1996
- ###########################################################################
-
- # The base manpages directory to put the man pages in
- @@ -101,6 +101,15 @@
- #VTP_OBJ = vt_mode.o
- ######################################
-
- +######################################
- +# WHICH AWK? awk is used for automatic prototype generation. GNU awk works
- +# where inferior awks don't. Sun is one manufacturer who supplies both
- +# a broken awk called 'awk' and a fixed one called 'nawk'. mkproto.awk will
- +# only work with the latter, and even that isn't as good as free GNU awk.
- +#
- +# Leave this uncommented; the OS-specific stuff will override it if required
- +AWK = awk
- +######################################
-
- #####################################
- # WHICH OPERATING SYSTEM?
- @@ -148,7 +157,7 @@
- # contributed by Andrew.Tridgell@anu.edu.au
- # FLAGSM = -DSUNOS4
- # LIBSM =
- -
- +# AWK = nawk
-
- # Use this for Linux with shadow passwords
- # contributed by Andrew.Tridgell@anu.edu.au
- @@ -177,6 +186,7 @@
- # contributed by Andrew.Tridgell@anu.edu.au
- # FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP
- # LIBSM = -lsocket -lnsl
- +# AWK = nawk
-
-
- # This is for SVR4
- @@ -491,8 +501,8 @@
- @echo "Using CFLAGS = $(CFLAGS)"
- @echo "Using LIBS = $(LIBS)"
-
- -INCLUDES1 = version.h local.h includes.h smb.h loadparm.h params.h smbpass.h
- -INCLUDES2 = pcap.h trans2.h reply.h
- +INCLUDES1 = version.h local.h includes.h smb.h smbpass.h
- +INCLUDES2 = trans2.h reply.h
- INCLUDES = $(INCLUDES1) $(INCLUDES2)
-
- UTILOBJ1 = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
- @@ -502,8 +512,10 @@
- SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
- SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o quotas.o uid.o
- SMBDOBJ = predict.o $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ)
- -NMBDOBJ1 = $(UTILOBJ) nmblib.o nameresp.o nmbsync.o nameannounce.o namedb.o nameelect.o
- -NMBDOBJ = $(NMBDOBJ1) namework.o nameserv.o clientutil.o
- +NMBDOBJ1 = nmblib.o namepacket.o nameresp.o nmbsync.o nameannounce.o nameelect.o
- +NMBDOBJ2 = namedbresp.o namedbwork.o namedbserver.o namedbsubnet.o namedbname.o
- +NMBDOBJ3 = nameservresp.o nameservreply.o namelogon.o namebrowse.o namework.o nameserv.o clientutil.o
- +NMBDOBJ = $(UTILOBJ) $(NMBDOBJ1) $(NMBDOBJ2) $(NMBDOBJ3)
- .SUFFIXES:
- .SUFFIXES: .c .o .h
-
- @@ -553,7 +565,7 @@
- @$(SHELL) $(srcdir)installbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
-
- installscripts:
- - @$(SHELL) $(srcdir)installscripts.sh $(INSTALLPERMS) $(BINDIR) $(srcdir)
- + @$(SHELL) $(srcdir)installscripts.sh $(INSTALLPERMS) $(BINDIR) $(SCRIPTS)
-
- # revert to the previously installed version
- revert:
- @@ -562,11 +574,23 @@
- installman:
- @$(SHELL) $(srcdir)installman.sh $(MANDIR) $(srcdir)
-
- +uninstall: uninstallman uninstallbin uninstallscripts
- +
- +uninstallman:
- + @$(SHELL) $(srcdir)uninstallman.sh $(MANDIR) $(srcdir)
- +
- +uninstallbin:
- + @$(SHELL) $(srcdir)uninstallbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
- +
- +uninstallscripts:
- + @$(SHELL) $(srcdir)uninstallscripts.sh $(INSTALLPERMS) $(BINDIR) $(SCRIPTS)
- +
- clean:
- rm -f core *.o *~ $(PROGS)
-
- proto:
- - cat *.c | awk -f mkproto.awk > proto.h
- + @$(SHELL) $(srcdir)checkos.sh $(FLAGSM)
- + $(AWK) -f mkproto.awk *.c > proto.h
-
- realclean: clean
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/access.c samba-1.9.16alpha11/source/access.c
- --- samba-1.9.16alpha10/source/access.c Mon Jun 10 15:18:48 1996
- +++ samba-1.9.16alpha11/source/access.c Mon Jul 15 17:55:03 1996
- @@ -5,7 +5,7 @@
- The code is used here with permission.
-
- The code has been considerably changed from the original. Bug reports
- -should be sent to Andrew.Tridgell@anu.edu.au
- +should be sent to samba-bugs@samba.anu.edu.au
- */
-
- #include "includes.h"
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/change-log samba-1.9.16alpha11/source/change-log
- --- samba-1.9.16alpha10/source/change-log Wed May 29 14:28:46 1996
- +++ samba-1.9.16alpha11/source/change-log Mon Jul 15 17:55:03 1996
- @@ -1,10 +1,13 @@
- -Change Log for Samba
- +SUPERCEDED Change Log for Samba
- +^^^^^^^^^^
-
- Unless otherwise attributed, all changes were made by
- -Andrew.Tridgell@anu.edu.au
- +Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.anu.edu.au.
-
- NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER
-
- +NOTE: From now on the cvs.log file will be used to give a complete log of
- +changes to samba. This change-log is now obsolete.
-
- 1.5.00 announced to mailing list
-
- @@ -1872,4 +1875,4 @@
- Tony Aiuto (tony@ics.com)
-
- make max disk size local
- -
- \ No newline at end of file
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/checkos.sh samba-1.9.16alpha11/source/checkos.sh
- --- samba-1.9.16alpha10/source/checkos.sh Sat May 4 17:50:25 1996
- +++ samba-1.9.16alpha11/source/checkos.sh Mon Jul 15 17:55:03 1996
- @@ -5,11 +5,11 @@
- You forgot to uncomment a host type and flags in the Makefile. If your
- host type does not appear in the Makefile then choose one that you
- think is similar and once you have it working then add a new host type
- -to the Makefile and includes.h. Please also send me the output of the
- +to the Makefile and includes.h. Please also send us the output of the
- command "uname" on your system so this can be automated at some future
- time.
-
- -Andrew.Tridgell@anu.edu.au
- +samba-bugs@samba.anu.edu.au
- =====================================================================
- EOF
- exit 1
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/client.c samba-1.9.16alpha11/source/client.c
- --- samba-1.9.16alpha10/source/client.c Mon Jun 10 15:18:49 1996
- +++ samba-1.9.16alpha11/source/client.c Thu Jul 18 20:53:15 1996
- @@ -2874,6 +2874,21 @@
- return(True);
- }
-
- +static struct {
- + int prot;
- + char *name;
- +} prots[] = {
- + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
- + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
- + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
- + {PROTOCOL_LANMAN1,"LANMAN1.0"},
- + {PROTOCOL_LANMAN2,"LM1.2X002"},
- + {PROTOCOL_LANMAN2,"Samba"},
- + {PROTOCOL_NT1,"NT LM 0.12"},
- + {PROTOCOL_NT1,"NT LANMAN 1.0"},
- + {-1,NULL}
- +};
- +
-
- /****************************************************************************
- send a login command
- @@ -2887,22 +2902,6 @@
- int sec_mode=0;
- int crypt_len;
- int max_vcs=0;
- - struct {
- - int prot;
- - char *name;
- - }
- - prots[] =
- - {
- - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
- - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
- - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
- - {PROTOCOL_LANMAN1,"LANMAN1.0"},
- - {PROTOCOL_LANMAN2,"LM1.2X002"},
- - {PROTOCOL_LANMAN2,"Samba"},
- - {PROTOCOL_NT1,"NT LM 0.12"},
- - {PROTOCOL_NT1,"NT LANMAN 1.0"},
- - {-1,NULL}
- - };
- char *pass = NULL;
- pstring dev;
- char *p;
- @@ -3586,7 +3585,7 @@
- /****************************************************************************
- try and browse available connections on a host
- ****************************************************************************/
- -static BOOL list_servers()
- +static BOOL list_servers(char *wk_grp)
- {
- char *rparam = NULL;
- char *rdata = NULL;
- @@ -3601,7 +3600,7 @@
- p = param;
- SSVAL(p,0,0x68); /* api number */
- p += 2;
- - strcpy(p,"WrLehDO");
- + strcpy(p,"WrLehDz");
- p = skip_string(p,1);
-
- strcpy(p,"B16BBDz");
- @@ -3616,6 +3615,11 @@
-
- SIVAL(p,0,SV_TYPE_ALL);
-
- + p += 4;
- +
- + strcpy(p, wk_grp);
- + p = skip_string(p,1);
- +
- if (call_api(PTR_DIFF(p+4,param),0,
- 8,10000,
- &rprcnt,&rdrcnt,
- @@ -3652,7 +3656,7 @@
- if (rparam) {free(rparam); rparam = NULL;}
- if (rdata) {free(rdata); rdata = NULL;}
-
- - SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
- + SIVAL(p,0,0x7fffffff);
-
- if (call_api(PTR_DIFF(p+4,param),0,
- 8,10000,
- @@ -4392,9 +4396,9 @@
- sleep(1);
- browse_host(True);
- }
- - if (!list_servers()) {
- + if (!list_servers(workgroup)) {
- sleep(1);
- - list_servers();
- + list_servers(workgroup);
- }
-
- send_logout();
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/cvs.log samba-1.9.16alpha11/source/cvs.log
- --- samba-1.9.16alpha10/source/cvs.log Mon Jun 10 15:21:07 1996
- +++ samba-1.9.16alpha11/source/cvs.log Thu Jul 18 20:54:26 1996
- @@ -1574,3 +1574,822 @@
- Log Message:
- preparing for release of 1.9.16alpha10
-
- +
- +****************************************
- +Date: Monday June 10, 1996 @ 16:08
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv6264
- +
- +Modified Files:
- + nameannounce.c namedb.c nameelect.c
- +Log Message:
- +minor patch to allow host announcements to remote subnets
- +
- +
- +
- +****************************************
- +Date: Wednesday June 12, 1996 @ 11:46
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv19858
- +
- +Modified Files:
- + charset.c
- +Log Message:
- +demo of cvs - ignore
- +
- +
- +
- +****************************************
- +Date: Friday June 14, 1996 @ 14:20
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv11409/samba/source
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Added option for specifying awk executable if not 'awk' initially for SunOSxx
- +Dan Shearer 14 June 96
- +
- +
- +
- +****************************************
- +Date: Tuesday June 18, 1996 @ 0:10
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv9310/samba/source
- +
- +Modified Files:
- + Makefile mkproto.awk
- +Log Message:
- +Added source filename to give crude index
- +Dan 17 June 1996
- +
- +
- +
- +****************************************
- +Date: Tuesday June 18, 1996 @ 1:36
- +Author: samba-bu
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/samba/samba-bugs/samba/source
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Fixed stupid bug introduced minutes ago
- +Dan
- +
- +
- +
- +****************************************
- +Date: Wednesday June 19, 1996 @ 22:23
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv29445
- +
- +Modified Files:
- + locking.c printing.c
- +Log Message:
- +- change date as a demo for john
- +- modified plp printing parser to work on my system
- +
- +
- +
- +****************************************
- +Date: Wednesday June 19, 1996 @ 22:27
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv29534
- +
- +Modified Files:
- + smbtar
- +Log Message:
- + - deleted reduntant blank line at end of file (JHT)
- +
- +
- +
- +****************************************
- +Date: Wednesday June 19, 1996 @ 23:23
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba
- +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba
- +
- +Modified Files:
- + README
- +Log Message:
- +Basic doc changes to keep up to date.
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Wednesday June 19, 1996 @ 23:23
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/docs
- +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba/docs
- +
- +Modified Files:
- + announce security_level.txt
- +Log Message:
- +Basic doc changes to keep up to date.
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Wednesday June 19, 1996 @ 23:23
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba/source
- +
- +Modified Files:
- + change-log proto.h system.c
- +Log Message:
- +Basic doc changes to keep up to date.
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Sunday June 30, 1996 @ 4:49
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv13629
- +
- +Modified Files:
- + Makefile loadparm.c mkproto.awk nameannounce.c namedb.c
- + nameelect.c nameresp.c nameserv.c nameserv.h namework.c nmbd.c
- + nmblookup.c nmbsync.c proto.h smb.h
- +Log Message:
- +
- +
- +luke's first attempt at using cvs
- +
- +accidentally updated the Makefile
- +
- +updated the name database structure (again!). this time, there is one
- +name database per local interface. there is also a pseudo-interface on
- +ip 255.255.255.255. its purpose is to store WINS name entries. all the
- +local interface name databases store SELF names only. the WINS name
- +database stores non-special browser names.
- +
- +added wins.dat file: records WINS entries in ascii format. this is reloaded
- +when nmbd restarts.
- +
- +added repeating code for response packets. timer is in seconds only at the
- +moment.
- +
- +updated the response queue code to deal with samba registering with a
- +WINS server a bit better (added more cases when a response isn't received).
- +tidied up the response packet processing code and expire_response_queue()
- +code. added cross references between response received and await-response
- +expired code.
- +
- +added over-zealous code that checks all machines that register with samba
- +as a WINS server (every 10 minutes i think): to see whether they are still
- +alive or not (see rfc1001.txt)
- +
- +bug reported by terry@ren.pc.athabascau.ca: DNSFAILed names _stay_ as
- +DNSFAIL, even though the machine may come back up and REGISTER.
- +
- +removed update_from_reg() function. it's not necessary, and it does too much.
- +
- +added code that announces on each local interface samba's ttl as zero and
- +servertype as zero when nmbd is kill -TERMed
- +
- +first attempt at putting the first functionality of samba browsing back in
- +(remote subnets should have samba appear in a workgroup specified through
- +the lmhosts file)
- +
- +lots of other miscellaneous tidying up / chopping about.
- +
- +
- +
- +****************************************
- +Date: Sunday June 30, 1996 @ 5:26
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv14098/samba/source
- +
- +Modified Files:
- + Makefile interface.c
- +Log Message:
- +
- +
- +added local and remote interfaces (didn't get done in first attempt)
- +
- +
- +
- +****************************************
- +Date: Sunday June 30, 1996 @ 21:00
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv9252
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +
- +
- +
- +
- +****************************************
- +Date: Tuesday July 2, 1996 @ 4:22
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv1723
- +
- +Added Files:
- + nameresp.doc nameserv.doc
- +Log Message:
- +
- +
- +first draft of low-level design documents describing the operation of
- +nameserv.c and nameresp.c and their interaction with the rest of nmbd.
- +
- +
- +
- +****************************************
- +Date: Tuesday July 2, 1996 @ 4:29
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv1885
- +
- +Modified Files:
- + nameresp.c nameserv.c proto.h
- +Log Message:
- +
- +
- +updated the NetBIOS code due to some bugs found by writing the first draft
- +of the low level design docs.
- +
- +
- +
- +****************************************
- +Date: Tuesday July 2, 1996 @ 4:53
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv2248
- +
- +Modified Files:
- + ipc.c
- +Log Message:
- +
- +
- +patch to fix NetServerEnum with multiple workgroup lists kindly supplied.
- +it works for him. needs testing.
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 1:22
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv22758
- +
- +Modified Files:
- + nameresp.doc nameserv.doc
- +Added Files:
- + namework.doc
- +Log Message:
- +
- +
- +updated low-level design documentation on nmbd. first draft of namework.doc
- +and updated the other two.
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 1:31
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv22894
- +
- +Modified Files:
- + nameserv.c namedb.c Makefile namework.c nameserv.h
- + nameannounce.c nameelect.c nameresp.c
- +Added Files:
- + namebrowse.c namelogon.c
- +Log Message:
- +
- +
- +as a result of the writing of namework.doc, namework.c has been tidied up,
- +some bugs fixed / documented and some discrepancies noted down (in
- +namework.c as well as namework.doc)
- +
- +namebrowse.c and namelogon.c contain functions that were inappropriately
- +placed in namework.c. namebrowse.c contains browse sync queue management
- +functions that were inappropriately placed in namedb.c
- +
- +the 'cmd_type' member of response_record has been renamed to 'state'
- +because that more accurately reflects it purpose (not entirely. sigh).
- +
- +fixed a bug in nameserv.c that meant the previous version wouldn't
- +compile.
- +
- +there's probably a bit more...
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 11:58
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv29605
- +
- +Modified Files:
- + client.c reply.c
- +Log Message:
- +- moved the protocol defs in the client to keep sill C compilers happy
- +- added change for cnum range in reply_tdis()
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 12:39
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv30677
- +
- +Modified Files:
- + Makefile proto.h
- +Log Message:
- +fix Makefile - remove Lukes private stuff :-)
- +rerun proto generator
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 12:58
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv30965
- +
- +Modified Files:
- + nameannounce.c
- +Log Message:
- +fixed conflict with global variable updatecount
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 12:58
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv31015
- +
- +Modified Files:
- + nameresp.c
- +Log Message:
- +fixed conflict between two variables called d
- +
- +
- +
- +****************************************
- +Date: Wednesday July 3, 1996 @ 12:58
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv31037
- +
- +Modified Files:
- + proto.h
- +Log Message:
- +generated new proto.h
- +
- +
- +
- +****************************************
- +Date: Thursday July 4, 1996 @ 13:16
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv22778/source
- +
- +Modified Files:
- + Makefile access.c change-log checkos.sh
- +Log Message:
- +Started uninstall in Makefile
- +Updated some email addresses
- +
- +
- +
- +****************************************
- +Date: Thursday July 4, 1996 @ 13:22
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv22827/source
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Put "which awk?" section in Makefile again
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Friday July 5, 1996 @ 5:19
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv6347
- +
- +Modified Files:
- + charset.c ipc.c namedb.c nameelect.c nameresp.c nameserv.c
- + nameserv.h nmbd.c nmbsync.c proto.h
- +Log Message:
- +
- +modified become_master() to a state-based system. becoming a master
- +is now performed in stages: wait for each NetBIOS name to be
- +successfully registered before proceeding to the next stage.
- +
- +tied implicit name registration and release (broadcast method) to the
- +same piece of code as explicit method (via WINS server).
- +
- +created special_browser_name() function that checks __MSBROWSE__
- +name: this name is ignored by WINS servers apparently.
- +
- +fixed likely incompatibility between refresh_my_names() and add_my_names().
- +(netbios entries were unlikely to be refreshed).
- +
- +NOTE: none of these changes have been tested. at all.
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Friday July 5, 1996 @ 5:40
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv6805
- +
- +Modified Files:
- + namebrowse.c proto.h
- +Log Message:
- +
- +namebrowse.c was using variable work uninitialised.
- +remkproto'd proto.h
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Friday July 5, 1996 @ 11:03
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv10304/source
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Updated Makefile - removed loadparam.h and friends - not needed??
- +
- +
- +
- +****************************************
- +Date: Friday July 5, 1996 @ 13:51
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv12406
- +
- +Modified Files:
- + Makefile installbin.sh installman.sh installscripts.sh
- +Log Message:
- +Changed install scripts so they don't have hardcoded values
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Friday July 5, 1996 @ 13:53
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv12511
- +
- +Added Files:
- + uninstallbin.sh uninstallman.sh uninstallscripts.sh
- +Log Message:
- +Added uninstallation from Makefile, either in parts or total uninstall
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Saturday July 6, 1996 @ 7:28
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv28271
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Call checkos in "make proto" in case of OS with broken awk && forgetful user,
- +because it looks very much like an awk bug otherwise.
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Saturday July 6, 1996 @ 7:31
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv28298
- +
- +Modified Files:
- + Makefile
- +Log Message:
- +Change awk to ($AWK) yet again :-)
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Sunday July 7, 1996 @ 22:36
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv28811
- +
- +Modified Files:
- + Makefile nameannounce.c namebrowse.c nameelect.c nameresp.c
- + nameresp.doc nameserv.c nameserv.doc nameserv.h namework.c
- + namework.doc
- +Added Files:
- + nameannounce.doc namebrowse.doc namedbname.doc namedbresp.doc
- + nameelect.doc namelogon.doc namepacket.doc namequery.doc
- + nameservreply.doc nameservresp.doc
- +Log Message:
- +
- +
- +tidied up: code shuffling and documentation.
- +created namedb*.c nameservresp.c nameservreply.c and namepacket.c
- +added modules to Makefile, downloading dan's current version first :-)
- +shuffled docs to match source
- +created more docs
- +
- +fixed bug in announce_backup() discovered when going nameannounce.doc:
- +backup list requests to the master browser should be used when samba is
- +not a master browser; backup list requests to the primary domain
- +controller should be used when samba is not a primary domain controller.
- +
- +fixed bug in sync_server: it would never send MasterAnnounce packets.
- +
- +removed the code that ignored special browser names: these should only
- +be ignored (except 0x1b names) when broadcasted name queries are sent,
- +not when directed registration or directed queries are sent samba as a
- +WINS server. (note: exactly what's going on is still uncertain).
- +
- +renamed NAME_QUERY_MST_SRV_CHK to NAME_QUERY_PDC_SRV_CHK (more accurate).
- +renamed NAME_STATUS_MST_SRV_CHK to NAME_STATUS_PDC_SRV_CHK (more accurate).
- +
- +added secured WINS name registration: a new 'state' NAME_REGISTER_CHALLENGE;
- +functions send_name_response(), response_name_query_register(); added
- +sending of WAIT ACKNOWLEDGEMENT packet; added a reply_to_ip field to
- +the response record structure so that after the name query challenge,
- +you know who to inform of the outcome of that challenge.
- +
- +note: these are all currently untested modifications (yikes!)
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Sunday July 7, 1996 @ 23:29
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv29341
- +
- +Modified Files:
- + Makefile namedb.c proto.h
- +Added Files:
- + namedbname.c namedbresp.c namedbserver.c namedbsubnet.c
- + namedbwork.c namepacket.c nameservreply.c nameservresp.c
- +Log Message:
- +
- +added the recently shuffled and updated source files missed in the
- +previous commit (see previous log message for details)
- +
- +fixed bug in nameservreply.c: wrong macro in use (RSSVAL not IVAL!).
- +
- +did another make proto
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Wednesday July 10, 1996 @ 4:01
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv9536
- +
- +Modified Files:
- + nameannounce.c namedbname.c namedbresp.c namedbserver.c
- + namedbsubnet.c namedbwork.c nameelect.c namepacket.c
- + nameresp.c nameserv.c namework.c
- +Log Message:
- +
- +sorted out various timer delay bugs: nameannounce.c nameserv.c
- +
- +namedbname.c:search_for_name() wasn't looking for 0x1b as well as
- +0x0 and 0x20 name types.
- +
- +reduced number of retransmissions of packets from 4 to 3 times.
- +
- +added code that ensures remote lmhosts entries don't get deleted when
- +a master browser cannot be found on a remote subnet. stopped forcing
- +an election on remote subnets if a master browser cannot be found.
- +
- +stopped browse list and wins list from being written out too frequently.
- +
- +only add samba's names to local interfaces.
- +
- +add 0x1c name if we are a domain logon machine (needs more exploration).
- +
- +why bother reloading services when receiving a SIGTERM?
- +
- +sort out add_my_name_entry() and remove_name_entry() to deal with
- +broadcast, samba as a WINS and samba using a WINS. properly.
- +
- +added extra debug information to help with expected response queue code.
- +updated debug comments in become_master().
- +
- +altered dump_names() DEBUG format. it looks prettier.
- +altered wins.dat format to match DEBUG format.
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Wednesday July 10, 1996 @ 4:11
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv9831
- +
- +Modified Files:
- + nmbd.c proto.h
- +Log Message:
- +
- +missed nmbd.c in previous update.
- +did a make proto
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Thursday July 11, 1996 @ 4:48
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv29974
- +
- +Modified Files:
- + ipc.c namedbresp.doc namedbsubnet.c nameelect.c nameelect.doc
- + nameresp.c nameserv.c nameserv.doc nameservreply.c
- + nameservreply.doc nameservresp.c nameservresp.doc proto.h
- +Removed Files:
- + namedb.c
- +Log Message:
- +
- +updated docs to match code mods from last two or three updates. done
- +some more commenting of code to match docs.
- +
- +sorted some bugs.
- +
- +ipc BOOL domains was uninitialised.
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Thursday July 11, 1996 @ 23:55
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/examples/simple
- +In directory arvidsjaur:/var/tmp/cvs-serv7090
- +
- +Modified Files:
- + smb.conf
- +Log Message:
- +Modified demo smb.conf to not have /tmp writeable by everyone by default.
- +According to server-linux some people seem to be uncommenting the example
- +[tmp] without thinking what it does :-)
- +
- +Dan
- +
- +
- +
- +****************************************
- +Date: Thursday July 18, 1996 @ 4:33
- +Author: samba-bugs
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv28303
- +
- +Modified Files:
- + client.c ipc.c nameannounce.c namedbname.c namedbserver.c
- + nameelect.c namepacket.c namequery.c nameresp.c nameresp.doc
- + nameserv.c nameserv.h nameservreply.c nameservresp.c
- + namework.c nmbd.c nmblookup.c proto.h version.h
- +Log Message:
- +
- +lots of changes to nmbd
- +
- +lkcl
- +
- +
- +
- +****************************************
- +Date: Thursday July 18, 1996 @ 20:08
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv11425
- +
- +Modified Files:
- + client.c
- +Log Message:
- +removed some debug stuff from luke
- +
- +
- +
- +****************************************
- +Date: Thursday July 18, 1996 @ 20:20
- +Author: tridge
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/var/tmp/cvs-serv11854
- +
- +Modified Files:
- + Makefile includes.h namework.c proto.h smb.h smbpass.c
- +Log Message:
- +minor cleanups ready for another release
- +
- +
- +
- +
- +****************************************
- +Date: Thursday July 18, 1996 @ 20:53
- +Author: samba-bu
- +
- +Update of /data/cvs/samba/source
- +In directory arvidsjaur:/samba/samba-bugs/samba/source
- +
- +Modified Files:
- + version.h
- +Log Message:
- +preparing for release of 1.9.16alpha11
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/includes.h samba-1.9.16alpha11/source/includes.h
- --- samba-1.9.16alpha10/source/includes.h Thu Jun 6 21:57:20 1996
- +++ samba-1.9.16alpha11/source/includes.h Thu Jul 18 20:53:15 1996
- @@ -984,9 +984,6 @@
- #include "nameserv.h"
- #include "proto.h"
- #include "byteorder.h"
- -#ifdef SMB_PASSWD
- -#include "smbpass.h"
- -#endif
-
- #include "kanji.h"
- #include "charset.h"
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installbin.sh samba-1.9.16alpha11/source/installbin.sh
- --- samba-1.9.16alpha10/source/installbin.sh Sat May 4 17:50:25 1996
- +++ samba-1.9.16alpha11/source/installbin.sh Mon Jul 15 17:55:03 1996
- @@ -34,7 +34,9 @@
- cat << EOF
- ======================================================================
- The binaries are installed. You may restore the old binaries (if there
- -were any) using the command "make revert"
- +were any) using the command "make revert". You may uninstall the binaries
- +using the command "make uninstallbin" or "make uninstall" to uninstall
- +binaries, man pages and shell scripts.
- ======================================================================
- EOF
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installman.sh samba-1.9.16alpha11/source/installman.sh
- --- samba-1.9.16alpha10/source/installman.sh Sat May 4 17:50:25 1996
- +++ samba-1.9.16alpha11/source/installman.sh Mon Jul 15 17:55:03 1996
- @@ -1,4 +1,6 @@
- #!/bin/sh
- +#5 July 96 Dan.Shearer@unisa.edu.au removed hardcoded values
- +
- MANDIR=$1
- SRCDIR=$2
-
- @@ -8,28 +10,29 @@
- if [ ! -d $d ]; then
- mkdir $d
- if [ ! -d $d ]; then
- - echo Failed to make directory $d
- + echo Failed to make directory $d, does $USER have privileges?
- exit 1
- fi
- fi
- done
-
- -cp $SRCDIR../docs/*.1 $MANDIR/man1
- -cp $SRCDIR../docs/*.5 $MANDIR/man5
- -cp $SRCDIR../docs/*.8 $MANDIR/man8
- -cp $SRCDIR../docs/*.7 $MANDIR/man7
- -echo Setting permissions on man pages
- -chmod 0644 $MANDIR/man1/smbstatus.1
- -chmod 0644 $MANDIR/man1/smbclient.1
- -chmod 0644 $MANDIR/man1/smbrun.1
- -chmod 0644 $MANDIR/man1/testparm.1
- -chmod 0644 $MANDIR/man1/testprns.1
- -chmod 0644 $MANDIR/man1/smbtar.1
- -chmod 0644 $MANDIR/man5/smb.conf.5
- -chmod 0644 $MANDIR/man7/samba.7
- -chmod 0644 $MANDIR/man8/smbd.8
- -chmod 0644 $MANDIR/man8/nmbd.8
- +for sect in 1 5 7 8 ; do
- + for m in $MANDIR/man$sect ; do
- + for s in $SRCDIR../docs/*$sect; do
- + FNAME=$m/`basename $s`
- + cp $s $m || echo Cannot create $FNAME... does $USER have privileges?
- + chmod 0644 $FNAME
- + done
- + done
- +done
- +
- +cat << EOF
- +======================================================================
- +The man pages have been installed. You may uninstall them using the command
- +the command "make uninstallman" or make "uninstall" to uninstall binaries,
- +man pages and shell scripts.
- +======================================================================
- +EOF
-
- -echo Man pages installed
- exit 0
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installscripts.sh samba-1.9.16alpha11/source/installscripts.sh
- --- samba-1.9.16alpha10/source/installscripts.sh Sat Jun 8 15:37:52 1996
- +++ samba-1.9.16alpha11/source/installscripts.sh Mon Jul 15 17:55:03 1996
- @@ -1,26 +1,43 @@
- #!/bin/sh
- # this script courtesy of James_K._Foote.PARC@xerox.com
- +# 5 July 96 Dan.Shearer@UniSA.Edu.Au Don't hardcode script names, get from Make
- +
- INSTALLPERMS=$1
- BINDIR=$2
- -SRCDIR=$3
- +
- +shift
- +shift
-
- echo Installing scripts in $BINDIR
-
- -for d in $BINDIR; do
- +for d in [ $BINDIR ]; do
- if [ ! -d $d ]; then
- mkdir $d
- if [ ! -d $d ]; then
- echo Failed to make directory $d
- + echo Have you run installbin first?
- exit 1
- fi
- fi
- done
-
- -cp ${SRCDIR}smbtar $BINDIR
- -cp ${SRCDIR}addtosmbpass $BINDIR
- -echo Setting permissions on scripts
- -chmod $INSTALLPERMS $BINDIR/smbtar
- -chmod $INSTALLPERMS $BINDIR/addtosmbpass
- +for p in $*; do
- + echo Installing $BINDIR/$p
- + cp $p $BINDIR/$p
- + if [ ! -f $BINDIR/$p ]; then
- + echo Cannot copy $p... does $USER have privileges?
- + fi
- + echo Setting permissions on $BINDIR/$p
- + chmod $INSTALLPERMS $BINDIR/$p
- +done
- +
- +cat << EOF
- +======================================================================
- +The scripts have been installed. You may uninstall them using
- +the command "make uninstallscripts" or "make install" to install binaries,
- +man pages and shell scripts. You may recover the previous version (if any
- +by "make revert".
- +======================================================================
- +EOF
-
- -echo Scripts installed
- exit 0
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/interface.c samba-1.9.16alpha11/source/interface.c
- --- samba-1.9.16alpha10/source/interface.c Mon Jun 10 15:18:51 1996
- +++ samba-1.9.16alpha11/source/interface.c Sun Jun 30 15:17:24 1996
- @@ -32,12 +32,9 @@
- static BOOL got_bcast=False;
- static BOOL got_nmask=False;
-
- -static struct interface {
- - struct interface *next;
- - struct in_addr ip;
- - struct in_addr bcast;
- - struct in_addr nmask;
- -} *interfaces = NULL;
- +struct interface *local_interfaces = NULL;
- +struct interface *remote_interfaces = NULL;
- +
- struct interface *last_iface;
-
- /****************************************************************************
- @@ -253,13 +250,12 @@
-
-
-
- -
- /****************************************************************************
- load a list of network interfaces
- ****************************************************************************/
- -void load_interfaces(void)
- +static void interpret_interfaces(char *s, struct interface **interfaces,
- + char *description)
- {
- - char *s = lp_interfaces();
- char *ptr = s;
- fstring token;
- struct interface *iface;
- @@ -278,7 +274,7 @@
- /* maybe we already have it listed */
- {
- struct interface *i;
- - for (i=interfaces;i;i=i->next)
- + for (i=(*interfaces);i;i=i->next)
- if (ip_equal(ip,i->ip)) break;
- if (i) continue;
- }
- @@ -299,18 +295,18 @@
- iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
- iface->next = NULL;
-
- - if (!interfaces) {
- - interfaces = iface;
- + if (!(*interfaces)) {
- + (*interfaces) = iface;
- } else {
- last_iface->next = iface;
- }
- last_iface = iface;
- - DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip)));
- + DEBUG(1,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
- DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast)));
- DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask)));
- }
-
- - if (interfaces) return;
- + if (*interfaces) return;
-
- /* setup a default interface */
- iface = (struct interface *)malloc(sizeof(*iface));
- @@ -339,7 +335,7 @@
- DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
- }
-
- - interfaces = last_iface = iface;
- + (*interfaces) = last_iface = iface;
-
- DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip)));
- DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast)));
- @@ -348,6 +344,21 @@
-
-
- /****************************************************************************
- +load the remote and local interfaces
- +****************************************************************************/
- +void load_interfaces(void)
- +{
- + /* add the machine's interfaces to local interface structure*/
- + interpret_interfaces(lp_interfaces (), &local_interfaces,
- + "interface");
- +
- + /* add all subnets to remote interfaces structure */
- + interpret_interfaces(lp_remote_interfaces(), &remote_interfaces,
- + "remote subnet");
- +}
- +
- +
- +/****************************************************************************
- override the defaults
- **************************************************************************/
- void iface_set_default(char *ip,char *bcast,char *nmask)
- @@ -375,7 +386,7 @@
- BOOL ismyip(struct in_addr ip)
- {
- struct interface *i;
- - for (i=interfaces;i;i=i->next)
- + for (i=local_interfaces;i;i=i->next)
- if (ip_equal(i->ip,ip)) return True;
- return False;
- }
- @@ -386,7 +397,7 @@
- BOOL ismybcast(struct in_addr bcast)
- {
- struct interface *i;
- - for (i=interfaces;i;i=i->next)
- + for (i=local_interfaces;i;i=i->next)
- if (ip_equal(i->bcast,bcast)) return True;
- return False;
- }
- @@ -399,7 +410,7 @@
- int ret = 0;
- struct interface *i;
-
- - for (i=interfaces;i;i=i->next)
- + for (i=local_interfaces;i;i=i->next)
- ret++;
- return ret;
- }
- @@ -411,7 +422,7 @@
- {
- struct interface *i;
-
- - for (i=interfaces;i && n;i=i->next)
- + for (i=local_interfaces;i && n;i=i->next)
- n--;
-
- if (i) return &i->ip;
- @@ -421,15 +432,14 @@
- static struct interface *iface_find(struct in_addr ip)
- {
- struct interface *i;
- - if (zero_ip(ip)) return interfaces;
- + if (zero_ip(ip)) return local_interfaces;
-
- - for (i=interfaces;i;i=i->next)
- + for (i=local_interfaces;i;i=i->next)
- if (same_net(i->ip,ip,i->nmask)) return i;
-
- - return interfaces;
- + return local_interfaces;
- }
-
- -
- /* these 3 functions return the ip/bcast/nmask for the interface
- most appropriate for the given ip address */
-
- @@ -447,5 +457,6 @@
- {
- return(&iface_find(ip)->ip);
- }
- +
-
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/loadparm.c samba-1.9.16alpha11/source/loadparm.c
- --- samba-1.9.16alpha10/source/loadparm.c Mon Jun 10 15:18:53 1996
- +++ samba-1.9.16alpha11/source/loadparm.c Sun Jun 30 15:17:25 1996
- @@ -129,6 +129,7 @@
- char *szSmbrun;
- char *szWINSserver;
- char *szInterfaces;
- + char *szRemoteInterfaces;
- int max_log_size;
- int mangled_stack;
- int max_xmit;
- @@ -366,6 +367,7 @@
- {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
- {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
- {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
- + {"remote interfaces",P_STRING, P_GLOBAL, &Globals.szRemoteInterfaces,NULL},
- {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
- {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
- {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
- @@ -704,6 +706,7 @@
- FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
- FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
- FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
- +FN_GLOBAL_STRING(lp_remote_interfaces,&Globals.szRemoteInterfaces)
-
- FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
- FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/locking.c samba-1.9.16alpha11/source/locking.c
- --- samba-1.9.16alpha10/source/locking.c Mon Jun 10 15:18:54 1996
- +++ samba-1.9.16alpha11/source/locking.c Sun Jun 30 15:17:25 1996
- @@ -2,7 +2,7 @@
- Unix SMB/Netbios implementation.
- Version 1.9.
- Locking functions
- - Copyright (C) Andrew Tridgell 1992-1995
- + Copyright (C) Andrew Tridgell 1992-1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/mkproto.awk samba-1.9.16alpha11/source/mkproto.awk
- --- samba-1.9.16alpha10/source/mkproto.awk Mon Jun 10 15:18:54 1996
- +++ samba-1.9.16alpha11/source/mkproto.awk Sun Jun 30 15:17:25 1996
- @@ -1,13 +1,17 @@
- -# generate prototypes for Samba C code
- -# tridge, June 1996
- -
- BEGIN {
- inheader=0;
- + current_file="";
- print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
- print ""
- }
-
- {
- + if (FILENAME!=current_file) {
- + print ""
- + print "/*The following definitions come from ",FILENAME," */"
- + print ""
- + current_file=FILENAME
- + }
- if (inheader) {
- if (match($0,"[)][ \t]*$")) {
- inheader = 0;
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameannounce.c samba-1.9.16alpha11/source/nameannounce.c
- --- samba-1.9.16alpha10/source/nameannounce.c Mon Jun 10 15:18:55 1996
- +++ samba-1.9.16alpha11/source/nameannounce.c Thu Jul 18 20:53:15 1996
- @@ -48,9 +48,7 @@
- extern int updatecount;
- extern int workgroup_count;
-
- -/* what server type are we currently */
- -
- -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
- +extern struct in_addr ipgrp;
-
- /****************************************************************************
- send a announce request to the local net
- @@ -72,12 +70,16 @@
- CVAL(p,0) = ANN_AnnouncementRequest;
- p++;
-
- - CVAL(p,0) = work->token; /* flags?? XXXX probably a token*/
- + CVAL(p,0) = work->token; /* (local) unique workgroup token id */
- p++;
- StrnCpy(p,myname,16);
- strupper(p);
- p = skip_string(p,1);
-
- + /* XXXX note: if we sent the announcement request to 0x1d instead
- + of 0x1e, then we could get the master browser to announce to
- + us instead of the members of the workgroup. wha-hey! */
- +
- send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
- }
- @@ -109,8 +111,32 @@
- myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
- }
-
- +
- +/****************************************************************************
- + find a server responsible for a workgroup, and sync browse lists
- + control ends up back here via response_name_query.
- + **************************************************************************/
- +void sync_server(enum state_type state, char *serv_name, char *work_name,
- + int name_type,
- + struct in_addr ip)
- +{
- + add_browser_entry(serv_name, name_type, work_name, 0, ip);
- +
- + if (state == NAME_STATUS_PDC_SRV_CHK)
- + {
- + /* announce ourselves as a master browser to serv_name */
- + do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
- + 0x20, 0, ip);
- + }
- +}
- +
- +
- /****************************************************************************
- construct a host announcement unicast
- +
- + this function should not be used heavily, and only when we are _not_
- + a master browser and _not_ a primary domain controller.
- +
- **************************************************************************/
- void announce_backup(void)
- {
- @@ -120,11 +146,19 @@
- char *p;
- struct subnet_record *d1;
- int tok;
- + static uint32 id_count = 0;
-
- if (!lastrun) lastrun = t;
- - if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60) return;
- +#if 1
- + if (t < lastrun + 1 * 60)
- +#else
- + if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
- +#endif
- + return;
- lastrun = t;
-
- + DEBUG(4,("checking backups...\n"));
- +
- for (tok = 0; tok <= workgroup_count; tok++)
- {
- for (d1 = subnetlist; d1; d1 = d1->next)
- @@ -139,18 +173,11 @@
-
- if (!work) continue;
-
- + if (AM_MASTER(work) && AM_DOMCTL(work)) continue;
- +
- /* found one: announce it across all domains */
- for (d = subnetlist; d; d = d->next)
- {
- - int type=0;
- -
- - if (AM_DOMCTL(work)) {
- - type = 0x1b;
- - } else if (AM_MASTER(work)) {
- - type = 0x1d;
- - } else {
- - continue;
- - }
-
- DEBUG(2,("sending announce backup %s workgroup %s(%d)\n",
- inet_ntoa(d->bcast_ip),work->work_group,
- @@ -158,20 +185,42 @@
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- +
- CVAL(p,0) = ANN_GetBackupListReq;
- - p++;
- -
- - CVAL(p,0) = 1; /* count? */
- - SIVAL(p,1,work->token); /* workgroup unique key index */
- - p += 5;
- - p++;
- + CVAL(p,1) = work->token; /* workgroup unique key index */
- + SIVAL(p,2,++id_count); /* unique count. not that we use it! */
- +
- + p += 6;
-
- - send_mailslot_reply(BROWSE_MAILSLOT,
- + debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
- +
- + if (!AM_DOMCTL(work))
- + {
- + /* only ask for a list of backup domain controllers
- + if we are not a domain controller ourselves */
- +
- + send_mailslot_reply(BROWSE_MAILSLOT,
- ClientDGRAM,outbuf,
- PTR_DIFF(p,outbuf),
- myname, work->work_group,
- - 0x0,type,d->bcast_ip,
- + 0x0,0x1b,d->bcast_ip,
- *iface_ip(d->bcast_ip));
- + }
- +
- + debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
- +
- + if (!AM_MASTER(work))
- + {
- + /* only ask for a list of master browsers if we
- + are not a master browser ourselves */
- +
- + send_mailslot_reply(BROWSE_MAILSLOT,
- + ClientDGRAM,outbuf,
- + PTR_DIFF(p,outbuf),
- + myname, work->work_group,
- + 0x0,0x1d,d->bcast_ip,
- + *iface_ip(d->bcast_ip));
- + }
- }
- }
- }
- @@ -179,19 +228,132 @@
-
-
- /****************************************************************************
- + send a host announcement packet
- + **************************************************************************/
- +static void do_announce_host(int command,
- + char *from_name, int from_type, struct in_addr from_ip,
- + char *to_name , int to_type , struct in_addr to_ip,
- + time_t announce_interval,
- + char *server_name, int server_type, char *server_comment)
- +{
- + pstring outbuf;
- + char *p;
- +
- + bzero(outbuf,sizeof(outbuf));
- + p = outbuf+1;
- +
- + /* command type */
- + CVAL(outbuf,0) = command;
- +
- + /* announcement parameters */
- + CVAL(p,0) = updatecount;
- + SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
- +
- + StrnCpy(p+5,server_name,16);
- + strupper(p+5);
- +
- + CVAL(p,21) = 0x02; /* major version */
- + CVAL(p,22) = 0x02; /* minor version */
- +
- + SIVAL(p,23,server_type);
- + SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
- + SSVAL(p,29,0xaa55); /* browse signature */
- +
- + strcpy(p+31,server_comment);
- + p += 31;
- + p = skip_string(p,1);
- +
- + debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
- +
- + /* send the announcement */
- + send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- + PTR_DIFF(p,outbuf),
- + from_name, to_name,
- + from_type, to_type,
- + to_ip, from_ip);
- +}
- +
- +
- +/****************************************************************************
- + remove all samba's server entries
- + ****************************************************************************/
- +void remove_my_servers(void)
- +{
- + struct subnet_record *d;
- + for (d = subnetlist; d; d = d->next)
- + {
- + struct work_record *work;
- + for (work = d->workgrouplist; work; work = work->next)
- + {
- + struct server_record *s;
- + for (s = work->serverlist; s; s = s->next)
- + {
- + if (!strequal(myname,s->serv.name)) continue;
- + announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
- + }
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- + announce a server entry
- + ****************************************************************************/
- +void announce_server(struct subnet_record *d, struct work_record *work,
- + char *name, char *comment, time_t ttl, int server_type)
- +{
- + uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
- +
- + if (AM_MASTER(work))
- + {
- + DEBUG(3,("sending local master announce to %s for %s(1e)\n",
- + inet_ntoa(d->bcast_ip),work->work_group));
- +
- + do_announce_host(ANN_LocalMasterAnnouncement,
- + name , 0x00, d->myip,
- + work->work_group, 0x1e, d->bcast_ip,
- + ttl*1000,
- + name, server_type, comment);
- +
- + DEBUG(3,("sending domain announce to %s for %s\n",
- + inet_ntoa(d->bcast_ip),work->work_group));
- +
- + /* XXXX should we do a domain-announce-kill? */
- + if (server_type != 0)
- + {
- + if (AM_DOMCTL(work)) {
- + domain_type |= SV_TYPE_DOMAIN_CTRL;
- + }
- + do_announce_host(ANN_DomainAnnouncement,
- + name , 0x00, d->myip,
- + MSBROWSE, 0x01, d->bcast_ip,
- + ttl*1000,
- + work->work_group, server_type ? domain_type : 0,
- + comment);
- + }
- + }
- + else
- + {
- + DEBUG(3,("sending host announce to %s for %s(1d)\n",
- + inet_ntoa(d->bcast_ip),work->work_group));
- +
- + do_announce_host(ANN_HostAnnouncement,
- + name , 0x00, d->myip,
- + work->work_group, 0x1d, d->bcast_ip,
- + ttl*1000,
- + name, server_type, comment);
- + }
- +}
- +
- +/****************************************************************************
- construct a host announcement unicast
- **************************************************************************/
- void announce_host(void)
- {
- time_t t = time(NULL);
- - pstring outbuf;
- - char *p;
- - char *namep;
- - char *stypep;
- - char *commentp;
- + struct subnet_record *d;
- pstring comment;
- char *my_name;
- - struct subnet_record *d;
-
- StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
-
- @@ -201,8 +363,7 @@
- {
- struct work_record *work;
-
- - if (!d->my_interface)
- - continue;
- + if (ip_equal(d->bcast_ip, ipgrp)) continue;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- @@ -210,11 +371,16 @@
- struct server_record *s;
- BOOL announce = False;
-
- + /* must work on the code that does announcements at up to
- + 30 seconds later if a master browser sends us a request
- + announce.
- + */
- +
- if (work->needannounce) {
- /* drop back to a max 3 minute announce - this is to prevent a
- single lost packet from stuffing things up for too long */
- - work->announce_interval = MIN(work->announce_interval,
- - CHECK_TIME_MIN_HOST_ANNCE*60);
- + work->announce_interval = MIN(work->announce_interval,
- + CHECK_TIME_MIN_HOST_ANNCE*60);
- work->lastannounce_time = t - (work->announce_interval+1);
- }
-
- @@ -242,85 +408,18 @@
- }
-
- if (announce)
- - {
- - bzero(outbuf,sizeof(outbuf));
- - p = outbuf+1;
- -
- - CVAL(p,0) = updatecount;
- - /* ms - despite the spec */
- - SIVAL(p,1,work->announce_interval*1000);
- - namep = p+5;
- - StrnCpy(namep,my_name,16);
- - strupper(namep);
- - CVAL(p,21) = 2; /* major version */
- - CVAL(p,22) = 2; /* minor version */
- - stypep = p+23;
- - SIVAL(p,23,stype);
- - SSVAL(p,27,0xaa55); /* browse signature */
- - SSVAL(p,29,1); /* browse version */
- - commentp = p+31;
- - strcpy(commentp,comment);
- - p = p+31;
- - p = skip_string(p,1);
- -
- - if (d->my_interface)
- - {
- - if (AM_MASTER(work))
- - {
- - SIVAL(stypep,0,work->ServerType);
- -
- - DEBUG(2,("sending local master announce to %s for %s\n",
- - inet_ntoa(d->bcast_ip),work->work_group));
- -
- - CVAL(outbuf,0) = ANN_LocalMasterAnnouncement;
- -
- - send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- - PTR_DIFF(p,outbuf),
- - my_name,work->work_group,0,
- - 0x1e,d->bcast_ip,
- - *iface_ip(d->bcast_ip));
- -
- - DEBUG(2,("sending domain announce to %s for %s\n",
- - inet_ntoa(d->bcast_ip),work->work_group));
- -
- - CVAL(outbuf,0) = ANN_DomainAnnouncement;
- -
- - StrnCpy(namep,work->work_group,15);
- - strupper(namep);
- - StrnCpy(commentp,myname,15);
- - strupper(commentp);
- -
- - SIVAL(stypep,0,(unsigned)0x80000000);
- - p = commentp + strlen(commentp) + 1;
- -
- - send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- - PTR_DIFF(p,outbuf),
- - my_name,MSBROWSE,0,0x01,d->bcast_ip,
- - *iface_ip(d->bcast_ip));
- - }
- - else
- - {
- - DEBUG(2,("sending host announce to %s for %s\n",
- - inet_ntoa(d->bcast_ip),work->work_group));
- -
- - CVAL(outbuf,0) = ANN_HostAnnouncement;
- -
- - send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- - PTR_DIFF(p,outbuf),
- - my_name,work->work_group,0,0x1d,
- - d->bcast_ip,*iface_ip(d->bcast_ip));
- - }
- - }
- - }
- + {
- + announce_server(d,work,my_name,comment,work->announce_interval,stype);
- + }
-
- if (work->needannounce)
- - {
- + {
- work->needannounce = False;
- break;
- /* sorry: can't do too many announces. do some more later */
- - }
- + }
- }
- - }
- + }
- }
-
-
- @@ -332,7 +431,7 @@
- least 15 minutes.
-
- this actually gets done in search_and_sync_workgroups() via the
- - MASTER_SERVER_CHECK command, if there is a response from the
- + NAME_QUERY_PDC_SRV_CHK command, if there is a response from the
- name query initiated here. see response_name_query()
- **************************************************************************/
- void announce_master(void)
- @@ -342,8 +441,9 @@
- time_t t = time(NULL);
- BOOL am_master = False; /* are we a master of some sort? :-) */
-
- - if (last && (t-last < CHECK_TIME_MST_ANNOUNCE * 60))
- - return;
- + if (!last) last = t;
- + if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
- + return;
-
- last = t;
-
- @@ -386,20 +486,20 @@
- struct in_addr ip;
- ip = ipzero;
-
- - queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
- - MASTER_SERVER_CHECK,
- - work->work_group,0x1b,0,
- - False, False, ip);
- + queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
- + NAME_QUERY_PDC_SRV_CHK,
- + work->work_group,0x1b,0,0,
- + False, False, ip, ip);
- }
- else
- {
- struct subnet_record *d2;
- for (d2 = subnetlist; d2; d2 = d2->next)
- {
- - queue_netbios_packet(ClientNMB,NMB_QUERY,
- - MASTER_SERVER_CHECK,
- - work->work_group,0x1b,0,
- - True, False, d2->bcast_ip);
- + queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- + NAME_QUERY_PDC_SRV_CHK,
- + work->work_group,0x1b,0,0,
- + True, False, d2->bcast_ip, d2->bcast_ip);
- }
- }
- }
- @@ -431,9 +531,9 @@
- /* check the existence of a pdc for this workgroup, and if
- one exists at the specified ip, sync with it and announce
- ourselves as a master browser to it */
- - queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
- - work->work_group,0x1b, 0,
- - bcast, False, ip);
- + queue_netbios_pkt_wins(d,ClientNMB, NMB_QUERY,NAME_QUERY_PDC_SRV_CHK,
- + work->work_group,0x1b, 0, 0,
- + bcast, False, ip, ip);
- }
- }
- }
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameannounce.doc samba-1.9.16alpha11/source/nameannounce.doc
- --- samba-1.9.16alpha10/source/nameannounce.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameannounce.doc Sun Jul 7 22:35:54 1996
- @@ -0,0 +1,137 @@
- +this module deals with announcements: the sending of announcement requests
- +and the sending of announcements either to refresh other servers' records
- +or as a response to announcement requests.
- +
- +
- +/*************************************************************************
- + announce_master()
- + *************************************************************************/
- +
- +this function is responsible for announcing samba as a master browser
- +to all known primary domain controllers.
- +
- +this announcement is sent out at CHECK_TIME_MST_ANNOUNCE minute
- +intervals, only if samba is a master browser on one or more of
- +its local interfaces.
- +
- +if no domain controller has been specified (lp_domain_controller())
- +samba goes through its list of servers looking for primary domain
- +controllers. when it finds one (other than itself) it will either
- +initiate a NAME_QUERY_PDC_SRV_CHK by broadcast or with a WINS
- +server. this will result in a NAME_STATUS_PDC_SRV_CHK, which
- +will result in a sync browse list and an announcement
- +ANN_MasterAnnounce being sent (see sync_server()).
- +
- +if a domain controller has been specified, samba will search for
- +a primary domain controller for its workgroup (either by directed
- +packet or by broadcast if it cannot resolve the domain controller
- +name using DNS), which results in the same action as listed above.
- +
- +
- +/*************************************************************************
- + announce_host()
- + *************************************************************************/
- +
- +this complex-looking function is responsible for announcing samba's
- +existence to other servers by broadcast. the actual announcement
- +is carried out by announce_server().
- +
- +the time period between samba's announcement will stretch from one
- +minute to twelve minutes by one minute. if samba has received an
- +announce request from a master browser, then it should answer at
- +any random interval between zero and thirty seconds after the
- +request is received. this is to ensure that the master browser
- +does not get overloaded with responses!
- +
- +
- +/*************************************************************************
- + announce_server()
- + *************************************************************************/
- +
- +this function is responsible for sending announcement packets.
- +these packets are received by other servers, which will then
- +update their records accordingly: what services we have, our
- +name, our comment field and our time to live (to name a few).
- +
- +if we are a master browser, then using do_announce_host() we
- +must send an announcement notifying members of that workgroup
- +that we are their master browser, and another announcement
- +indicating to all backup browsers and master browsers that
- +we are a master browser.
- +
- +(note: if another master browser receives this announcement
- +and thinks that it is also the master browser for this
- +workgroup, it stops being a master browser and forces an
- +election).
- +
- +if we are not a master browser, then we send an announcement
- +notifying the master browser that we are a member of its
- +workgroup.
- +
- +
- +/*************************************************************************
- + remove_my_servers()
- + *************************************************************************/
- +
- +this function is responsible for informing other servers that
- +samba is about to go down. it announces, on all subnets, that
- +samba's time to live is zero and that it has no services.
- +
- +
- +/*************************************************************************
- + do_announce_host()
- + *************************************************************************/
- +
- +this function is responsible for sending out an announcement
- +MAILSLOT browse packet. it contains information such as the
- +time to live, name of the server, services that the server
- +offers etc.
- +
- +the format of this MAILSLOT browse packet is described in
- +draft-heizer-cifs-v1-spec-00.txt 3.9.50.4.1 page 165-6.
- +
- +
- +/*************************************************************************
- + announce_backup()
- + *************************************************************************/
- +
- +this function is responsible for getting master browsers and domain
- +controllers to send us lists of backup servers. this is done by
- +sending an ANN_GetBackupListReq browse mailslot.
- +
- +the master browser, or primary domain controller, should respond
- +with an ANN_GetBackupListResp browse mailslot containing the list
- +of backup servers.
- +
- +
- +/*************************************************************************
- + sync_server()
- + *************************************************************************/
- +
- +this function is responsible for initiating a sync browse list
- +sequence and, if necessary, carrying out an ANN_MasterAnnouncement
- +to the primary domain controller (that we are also sync'ing
- +browse lists with).
- +
- +see nameservresp.c:response_name_status_check().
- +
- +
- +/*************************************************************************
- + announce_request()
- + *************************************************************************/
- +
- +this function is responsible for sending an announcement request to
- +another server. this server should respond with an announcement.
- +
- +if the announce request is sent to WORKGROUP(0x1e) then members of
- +the workgroup will respond (with ANN_HostAnnounce packets)
- +
- +if the announce request is sent to WORKGROUP(0x1d) then the master
- +browser of the workgroup should respond (ANN_LocalMasterAnnounce).
- +this is untested.
- +
- +if the announce request is sent to ^1^2__MSBROWSE__^2(0x1) then
- +(and this is pure speculation), all backup browsers and master
- +browsers should respond with ANN_DomainAnnounce packets.
- +this is untested.
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namebrowse.c samba-1.9.16alpha11/source/namebrowse.c
- --- samba-1.9.16alpha10/source/namebrowse.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namebrowse.c Sun Jul 7 22:35:54 1996
- @@ -0,0 +1,217 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- +*/
- +
- +#include "includes.h"
- +#include "smb.h"
- +
- +extern int ClientNMB;
- +
- +extern int DEBUGLEVEL;
- +
- +/* this is our browse master/backup cache database */
- +static struct browse_cache_record *browserlist = NULL;
- +
- +
- +/***************************************************************************
- + add a browser into the list
- + **************************************************************************/
- +static void add_browse_cache(struct browse_cache_record *b)
- +{
- + struct browse_cache_record *b2;
- +
- + if (!browserlist)
- + {
- + browserlist = b;
- + b->prev = NULL;
- + b->next = NULL;
- + return;
- + }
- +
- + for (b2 = browserlist; b2->next; b2 = b2->next) ;
- +
- + b2->next = b;
- + b->next = NULL;
- + b->prev = b2;
- +}
- +
- +
- +/*******************************************************************
- + remove old browse entries
- + ******************************************************************/
- +void expire_browse_cache(time_t t)
- +{
- + struct browse_cache_record *b;
- + struct browse_cache_record *nextb;
- +
- + /* expire old entries in the serverlist */
- + for (b = browserlist; b; b = nextb)
- + {
- + if (b->synced && b->sync_time < t)
- + {
- + DEBUG(3,("Removing dead cached browser %s\n",b->name));
- + nextb = b->next;
- +
- + if (b->prev) b->prev->next = b->next;
- + if (b->next) b->next->prev = b->prev;
- +
- + if (browserlist == b) browserlist = b->next;
- +
- + free(b);
- + }
- + else
- + {
- + nextb = b->next;
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- + add a browser entry
- + ****************************************************************************/
- +struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- + time_t ttl, struct in_addr ip)
- +{
- + BOOL newentry=False;
- +
- + struct browse_cache_record *b;
- +
- + /* search for the entry: if it's already in the cache, update that entry */
- + for (b = browserlist; b; b = b->next)
- + {
- + if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
- + }
- +
- + if (b && b->synced)
- + {
- + /* entries get left in the cache for a while. this stops sync'ing too
- + often if the network is large */
- + DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
- + b->name, b->group, inet_ntoa(b->ip), b->sync_time));
- + return NULL;
- + }
- +
- + if (!b)
- + {
- + newentry = True;
- + b = (struct browse_cache_record *)malloc(sizeof(*b));
- +
- + if (!b) return(NULL);
- +
- + bzero((char *)b,sizeof(*b));
- + }
- +
- + /* update the entry */
- + ttl = time(NULL)+ttl;
- +
- + StrnCpy(b->name ,name,sizeof(b->name )-1);
- + StrnCpy(b->group,wg ,sizeof(b->group)-1);
- + strupper(b->name);
- + strupper(b->group);
- +
- + b->ip = ip;
- + b->type = type;
- +
- + if (newentry || ttl < b->sync_time)
- + b->sync_time = ttl;
- +
- + if (newentry)
- + {
- + b->synced = False;
- + add_browse_cache(b);
- +
- + DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
- + wg, name, type, inet_ntoa(ip),ttl));
- + }
- + else
- + {
- + DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
- + wg, name, type, inet_ntoa(ip),ttl));
- + }
- +
- + return(b);
- +}
- +
- +
- +/****************************************************************************
- +find a server responsible for a workgroup, and sync browse lists
- +**************************************************************************/
- +static void start_sync_browse_entry(struct browse_cache_record *b)
- +{
- + struct subnet_record *d;
- + struct work_record *work;
- +
- + if (!(d = find_subnet(b->ip))) return;
- +
- + if (!(work = find_workgroupstruct(d, b->group, False))) return;
- +
- + /* only sync if we are the master */
- + if (AM_MASTER(work)) {
- +
- + /* first check whether the group we intend to sync with exists. if it
- + doesn't, the server must have died. o dear. */
- +
- + /* see response_netbios_packet() or expire_netbios_response_entries() */
- + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SYNC,
- + b->group,0x20,0,0,
- + False,False,b->ip,b->ip);
- + }
- +
- + b->synced = True;
- +}
- +
- +
- +/****************************************************************************
- + search through browser list for an entry to sync with
- + **************************************************************************/
- +void do_browser_lists(void)
- +{
- + struct browse_cache_record *b;
- + static time_t last = 0;
- + time_t t = time(NULL);
- +
- + if (t-last < 20) return; /* don't do too many of these at once! */
- + /* XXXX equally this period should not be too long
- + the server may die in the intervening gap */
- +
- + last = t;
- +
- + /* pick any entry in the list, preferably one whose time is up */
- + for (b = browserlist; b && b->next; b = b->next)
- + {
- + if (b->sync_time < t && b->synced == False) break;
- + }
- +
- + if (b && !b->synced)
- + {
- + /* sync with the selected entry then remove some dead entries */
- + start_sync_browse_entry(b);
- + expire_browse_cache(t - 60);
- + }
- +
- +}
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namebrowse.doc samba-1.9.16alpha11/source/namebrowse.doc
- --- samba-1.9.16alpha10/source/namebrowse.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namebrowse.doc Sun Jul 7 22:35:54 1996
- @@ -0,0 +1,69 @@
- +this module deals with queueing servers that samba must sync browse
- +lists with. it will always issue a name query immediately before
- +actually carrying out the NetServerEnum call, to ensure that time
- +is not wasted by a remote server's failure.
- +
- +this module was created to minimise the amount of NetServerEnum calls
- +that samba may be asked to perform, by maintaining the name of a server
- +for up to a minute after the NetServerEnum call was issued, and
- +disallowing further NetServerEnum calls to this remote server until
- +the entry is removed.
- +
- +samba can ask for a NetServerEnum call to be issued to grab a remote
- +server's list of servers and workgroups either in its capacity as
- +a primary domain controller (domain master browser), as a local
- +master browser.
- +
- +samba does not deal with becoming a backup master browser properly
- +at present.
- +
- +
- +/*************************************************************************
- + do_browser_lists()
- + *************************************************************************/
- +
- +this function is responsible for finding an appropriate entry in the
- +sync browser cache, initiating a name query (which results in a
- +NetServerEnum call if there is a positive response), and then
- +removing all entries that have been actioned and have been around
- +for over a minute.
- +
- +
- +/*************************************************************************
- + start_sync_browse_entry()
- + *************************************************************************/
- +
- +this function is responsible for initiating a name query. if a
- +positive response is received, then this will result in a
- +NetServerEnum api call.
- +
- +samba will only initiate this process if it is a master browser
- +for this workgroup.
- +
- +
- +/*************************************************************************
- + add_browser_entry()
- + *************************************************************************/
- +
- +this function is responsible for adding a browser into the list of
- +servers to sync browse lists with. if the server entry has already
- +been added and syncing browse lists has already been initiated, it
- +will not be added again.
- +
- +
- +/*************************************************************************
- + expire_browse_cache()
- + *************************************************************************/
- +
- +this function is responsible for removing entries that have had the
- +sync browse list initiated (whether that succeeded or not is beyond
- +this function's scope) and have been in the cache for a while.
- +
- +
- +/*************************************************************************
- + add_browse_entry()
- + *************************************************************************/
- +
- +this function is responsible for adding a new entry into the list
- +of servers to sync browse lists with at some point in the near future.
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedb.c samba-1.9.16alpha11/source/namedb.c
- --- samba-1.9.16alpha10/source/namedb.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/namedb.c Thu Jan 1 10:00:00 1970
- @@ -1,720 +0,0 @@
- -/*
- - Unix SMB/Netbios implementation.
- - Version 1.9.
- - NBT netbios routines and daemon - version 2
- - Copyright (C) Andrew Tridgell 1994-1995
- -
- - This program is free software; you can redistribute it and/or modify
- - it under the terms of the GNU General Public License as published by
- - the Free Software Foundation; either version 2 of the License, or
- - (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU General Public License for more details.
- -
- - You should have received a copy of the GNU General Public License
- - along with this program; if not, write to the Free Software
- - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- -
- - Revision History:
- -
- - 14 jan 96: lkcl@pires.co.uk
- - added multiple workgroup domain master support
- -
- -*/
- -
- -#include "includes.h"
- -#include "smb.h"
- -
- -extern int ClientNMB;
- -extern int ClientDGRAM;
- -
- -extern int DEBUGLEVEL;
- -
- -extern time_t StartupTime;
- -extern pstring myname;
- -extern pstring scope;
- -
- -extern struct in_addr ipgrp;
- -
- -/* this is our browse master/backup cache database */
- -struct browse_cache_record *browserlist = NULL;
- -
- -/* this is our domain/workgroup/server database */
- -struct subnet_record *subnetlist = NULL;
- -
- -static BOOL updatedlists = True;
- -int updatecount=0;
- -
- -int workgroup_count = 0; /* unique index key: one for each workgroup */
- -
- -/* what server type are we currently */
- -
- -#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
- - SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
- - SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
- -
- -
- -/****************************************************************************
- - add a workgroup into the domain list
- - **************************************************************************/
- -static void add_workgroup(struct work_record *work, struct subnet_record *d)
- -{
- - struct work_record *w2;
- -
- - if (!work || !d) return;
- -
- - if (!d->workgrouplist)
- - {
- - d->workgrouplist = work;
- - work->prev = NULL;
- - work->next = NULL;
- - return;
- - }
- -
- - for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
- -
- - w2->next = work;
- - work->next = NULL;
- - work->prev = w2;
- -}
- -
- -
- -/****************************************************************************
- - create a blank workgroup
- - **************************************************************************/
- -static struct work_record *make_workgroup(char *name)
- -{
- - struct work_record *work;
- - struct subnet_record *d;
- - int t = -1;
- -
- - if (!name || !name[0]) return NULL;
- -
- - work = (struct work_record *)malloc(sizeof(*work));
- - if (!work) return(NULL);
- -
- - StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- - work->serverlist = NULL;
- -
- - work->ServerType = DFLT_SERVER_TYPE;
- - work->RunningElection = False;
- - work->ElectionCount = 0;
- - work->needelection = False;
- - work->needannounce = True;
- -
- - /* make sure all token representations of workgroups are unique */
- -
- - for (d = subnetlist; d && t == -1; d = d->next)
- - {
- - struct work_record *w;
- - for (w = d->workgrouplist; w && t == -1; w = w->next)
- - {
- - if (strequal(w->work_group, work->work_group)) t = w->token;
- - }
- - }
- -
- - if (t == -1)
- - {
- - work->token = ++workgroup_count;
- - }
- - else
- - {
- - work->token = t;
- - }
- -
- -
- - /* WfWg uses 01040b01 */
- - /* Win95 uses 01041501 */
- - /* NTAS uses ???????? */
- - work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
- - work->ElectionCriterion |= (lp_os_level() << 24);
- - if (lp_domain_master()) {
- - work->ElectionCriterion |= 0x80;
- - }
- -
- - return work;
- -}
- -
- -
- -/*******************************************************************
- - expire old servers in the serverlist
- - time of -1 indicates everybody dies
- - ******************************************************************/
- -static void remove_old_servers(struct work_record *work, time_t t)
- -{
- - struct server_record *s;
- - struct server_record *nexts;
- -
- - /* expire old entries in the serverlist */
- - for (s = work->serverlist; s; s = nexts)
- - {
- - if (t == -1 || (s->death_time && s->death_time < t))
- - {
- - DEBUG(3,("Removing dead server %s\n",s->serv.name));
- - updatedlists = True;
- - nexts = s->next;
- -
- - if (s->prev) s->prev->next = s->next;
- - if (s->next) s->next->prev = s->prev;
- -
- - if (work->serverlist == s)
- - work->serverlist = s->next;
- -
- - free(s);
- - }
- - else
- - {
- - nexts = s->next;
- - }
- - }
- -}
- -
- -
- -/*******************************************************************
- - remove workgroups
- - ******************************************************************/
- -struct work_record *remove_workgroup(struct subnet_record *d,
- - struct work_record *work)
- -{
- - struct work_record *ret_work = NULL;
- -
- - if (!d || !work) return NULL;
- -
- - DEBUG(3,("Removing old workgroup %s\n", work->work_group));
- -
- - remove_old_servers(work, -1);
- -
- - ret_work = work->next;
- -
- - if (work->prev) work->prev->next = work->next;
- - if (work->next) work->next->prev = work->prev;
- -
- - if (d->workgrouplist == work) d->workgrouplist = work->next;
- -
- - free(work);
- -
- - return ret_work;
- -}
- -
- -
- -/****************************************************************************
- - add a domain into the list
- - **************************************************************************/
- -static void add_subnet(struct subnet_record *d)
- -{
- - struct subnet_record *d2;
- -
- - if (!subnetlist)
- - {
- - subnetlist = d;
- - d->prev = NULL;
- - d->next = NULL;
- - return;
- - }
- -
- - for (d2 = subnetlist; d2->next; d2 = d2->next);
- -
- - d2->next = d;
- - d->next = NULL;
- - d->prev = d2;
- -}
- -
- -/***************************************************************************
- - add a browser into the list
- - **************************************************************************/
- -static void add_browse_cache(struct browse_cache_record *b)
- -{
- - struct browse_cache_record *b2;
- -
- - if (!browserlist)
- - {
- - browserlist = b;
- - b->prev = NULL;
- - b->next = NULL;
- - return;
- - }
- -
- - for (b2 = browserlist; b2->next; b2 = b2->next) ;
- -
- - b2->next = b;
- - b->next = NULL;
- - b->prev = b2;
- -}
- -
- -
- -/***************************************************************************
- - add a server into the list
- - **************************************************************************/
- -static void add_server(struct work_record *work,struct server_record *s)
- -{
- - struct server_record *s2;
- -
- - if (!work->serverlist) {
- - work->serverlist = s;
- - s->prev = NULL;
- - s->next = NULL;
- - return;
- - }
- -
- - for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
- -
- - s2->next = s;
- - s->next = NULL;
- - s->prev = s2;
- -}
- -
- -
- -/*******************************************************************
- - remove old browse entries
- - ******************************************************************/
- -void expire_browse_cache(time_t t)
- -{
- - struct browse_cache_record *b;
- - struct browse_cache_record *nextb;
- -
- - /* expire old entries in the serverlist */
- - for (b = browserlist; b; b = nextb)
- - {
- - if (b->synced && b->sync_time < t)
- - {
- - DEBUG(3,("Removing dead cached browser %s\n",b->name));
- - nextb = b->next;
- -
- - if (b->prev) b->prev->next = b->next;
- - if (b->next) b->next->prev = b->prev;
- -
- - if (browserlist == b) browserlist = b->next;
- -
- - free(b);
- - }
- - else
- - {
- - nextb = b->next;
- - }
- - }
- -}
- -
- -
- -/****************************************************************************
- - find a workgroup in the workgrouplist
- - only create it if the domain allows it, or the parameter 'add' insists
- - that it get created/added anyway. this allows us to force entries in
- - lmhosts file to be added.
- - **************************************************************************/
- -struct work_record *find_workgroupstruct(struct subnet_record *d,
- - fstring name, BOOL add)
- -{
- - struct work_record *ret, *work;
- -
- - if (!d) return NULL;
- -
- - DEBUG(4, ("workgroup search for %s: ", name));
- -
- - if (strequal(name, "*"))
- - {
- - DEBUG(2,("add any workgroups: initiating browser search on %s\n",
- - inet_ntoa(d->bcast_ip)));
- - queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
- - MSBROWSE,0x1,0,
- - True,False, d->bcast_ip);
- - return NULL;
- - }
- -
- - for (ret = d->workgrouplist; ret; ret = ret->next) {
- - if (!strcmp(ret->work_group,name)) {
- - DEBUG(4, ("found\n"));
- - return(ret);
- - }
- - }
- -
- - if (!add) {
- - DEBUG(4, ("not found\n"));
- - return NULL;
- - }
- -
- - DEBUG(4,("not found: creating\n"));
- -
- - if ((work = make_workgroup(name)))
- - {
- - if (lp_preferred_master() &&
- - strequal(lp_workgroup(), name) &&
- - d->my_interface)
- - {
- - DEBUG(3, ("preferred master startup for %s\n", work->work_group));
- - work->needelection = True;
- - work->ElectionCriterion |= (1<<3);
- - }
- - if (!d->my_interface)
- - {
- - work->needelection = False;
- - }
- - add_workgroup(work, d);
- - return(work);
- - }
- - return NULL;
- -}
- -
- -/****************************************************************************
- - find a domain in the subnetlist
- - **************************************************************************/
- -struct subnet_record *find_domain(struct in_addr ip)
- -{
- - struct subnet_record *d;
- -
- - /* search through domain list for broadcast/netmask that matches
- - the source ip address */
- -
- - for (d = subnetlist; d; d = d->next)
- - {
- - if (same_net(ip, d->bcast_ip, d->mask_ip))
- - return(d);
- - }
- -
- - return (NULL);
- -}
- -
- -
- -/****************************************************************************
- - dump a copy of the workgroup/domain database
- - **************************************************************************/
- -void dump_workgroups(void)
- -{
- - struct subnet_record *d;
- -
- - for (d = subnetlist; d; d = d->next)
- - {
- - if (d->workgrouplist)
- - {
- - struct work_record *work;
- -
- - DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
- - DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
- -
- - for (work = d->workgrouplist; work; work = work->next)
- - {
- - DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
- - if (work->serverlist)
- - {
- - struct server_record *s;
- - for (s = work->serverlist; s; s = s->next)
- - {
- - DEBUG(4,("\t\t%s %8x (%s)\n",
- - s->serv.name, s->serv.type, s->serv.comment));
- - }
- - }
- - }
- - }
- - }
- -}
- -
- -/****************************************************************************
- - create a domain entry
- - ****************************************************************************/
- -static struct subnet_record *make_subnet(struct in_addr bcast_ip,
- - struct in_addr mask)
- -{
- - struct subnet_record *d;
- - d = (struct subnet_record *)malloc(sizeof(*d));
- -
- - if (!d) return(NULL);
- -
- - bzero((char *)d,sizeof(*d));
- -
- - DEBUG(4,("making subnet %s ", inet_ntoa(bcast_ip)));
- - DEBUG(4,("%s\n", inet_ntoa(mask)));
- -
- - d->bcast_ip = bcast_ip;
- - d->mask_ip = mask;
- - d->workgrouplist = NULL;
- - d->my_interface = ismybcast(d->bcast_ip);
- -
- - add_subnet(d);
- -
- - return d;
- -}
- -
- -/****************************************************************************
- - add a domain entry. creates a workgroup, if necessary, and adds the domain
- - to the named a workgroup.
- - ****************************************************************************/
- -struct subnet_record *add_subnet_entry(struct in_addr source_ip,
- - struct in_addr source_mask,
- - char *name, BOOL add)
- -{
- - struct subnet_record *d;
- - struct in_addr ip;
- -
- - ip = ipgrp;
- -
- - if (zero_ip(source_ip))
- - source_ip = *iface_bcast(source_ip);
- -
- - /* add the domain into our domain database */
- - if ((d = find_domain(source_ip)) ||
- - (d = make_subnet(source_ip, source_mask)))
- - {
- - struct work_record *w = find_workgroupstruct(d, name, add);
- -
- - if (!w) return NULL;
- -
- - /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
- - or register with WINS server, if it's our workgroup */
- - if (strequal(lp_workgroup(), name))
- - {
- - extern pstring ServerComment;
- - add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
- - add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
- - add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
- - }
- -
- - DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
- - return d;
- - }
- - return NULL;
- -}
- -
- -/****************************************************************************
- - add a browser entry
- - ****************************************************************************/
- -struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- - time_t ttl, struct in_addr ip)
- -{
- - BOOL newentry=False;
- -
- - struct browse_cache_record *b;
- -
- - /* search for the entry: if it's already in the cache, update that entry */
- - for (b = browserlist; b; b = b->next)
- - {
- - if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
- - }
- -
- - if (b && b->synced)
- - {
- - /* entries get left in the cache for a while. this stops sync'ing too
- - often if the network is large */
- - DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
- - b->name, b->group, inet_ntoa(b->ip), b->sync_time));
- - return NULL;
- - }
- -
- - if (!b)
- - {
- - newentry = True;
- - b = (struct browse_cache_record *)malloc(sizeof(*b));
- -
- - if (!b) return(NULL);
- -
- - bzero((char *)b,sizeof(*b));
- - }
- -
- - /* update the entry */
- - ttl = time(NULL)+ttl;
- -
- - StrnCpy(b->name ,name,sizeof(b->name )-1);
- - StrnCpy(b->group,wg ,sizeof(b->group)-1);
- - strupper(b->name);
- - strupper(b->group);
- -
- - b->ip = ip;
- - b->type = type;
- -
- - if (newentry || ttl < b->sync_time)
- - b->sync_time = ttl;
- -
- - if (newentry)
- - {
- - b->synced = False;
- - add_browse_cache(b);
- -
- - DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
- - wg, name, type, inet_ntoa(ip),ttl));
- - }
- - else
- - {
- - DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
- - wg, name, type, inet_ntoa(ip),ttl));
- - }
- -
- - return(b);
- -}
- -
- -
- -/****************************************************************************
- - add a server entry
- - ****************************************************************************/
- -struct server_record *add_server_entry(struct subnet_record *d,
- - struct work_record *work,
- - char *name,int servertype,
- - int ttl,char *comment,
- - BOOL replace)
- -{
- - BOOL newentry=False;
- - struct server_record *s;
- -
- - if (name[0] == '*')
- - {
- - return (NULL);
- - }
- -
- - for (s = work->serverlist; s; s = s->next)
- - {
- - if (strequal(name,s->serv.name)) break;
- - }
- -
- - if (s && !replace)
- - {
- - DEBUG(4,("Not replacing %s\n",name));
- - return(s);
- - }
- -
- - updatedlists=True;
- -
- - if (!s)
- - {
- - newentry = True;
- - s = (struct server_record *)malloc(sizeof(*s));
- -
- - if (!s) return(NULL);
- -
- - bzero((char *)s,sizeof(*s));
- - }
- -
- - if (d->my_interface &&
- - strequal(lp_workgroup(),work->work_group))
- - {
- - if (servertype)
- - servertype |= SV_TYPE_LOCAL_LIST_ONLY;
- - }
- - else
- - {
- - servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
- - }
- -
- - /* update the entry */
- - StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
- - StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
- - strupper(s->serv.name);
- - s->serv.type = servertype;
- - s->death_time = ttl?time(NULL)+ttl*3:0;
- -
- - if (servertype == 0)
- - s->death_time = time(NULL)-1;
- -
- - /* for a domain entry, the comment field refers to the server name */
- -
- - if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
- -
- - if (newentry)
- - {
- - add_server(work, s);
- -
- - DEBUG(3,("Added "));
- - }
- - else
- - {
- - DEBUG(3,("Updated "));
- - }
- -
- - DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
- - name,servertype,comment,
- - work->work_group,inet_ntoa(d->bcast_ip)));
- -
- - return(s);
- -}
- -
- -
- -/*******************************************************************
- - write out browse.dat
- - ******************************************************************/
- -void write_browse_list(void)
- -{
- - struct subnet_record *d;
- -
- - pstring fname,fnamenew;
- - FILE *f;
- -
- - if (!updatedlists) return;
- -
- - dump_names();
- - dump_workgroups();
- -
- - updatedlists = False;
- - updatecount++;
- -
- - strcpy(fname,lp_lockdir());
- - trim_string(fname,NULL,"/");
- - strcat(fname,"/");
- - strcat(fname,SERVER_LIST);
- - strcpy(fnamenew,fname);
- - strcat(fnamenew,".");
- -
- - f = fopen(fnamenew,"w");
- -
- - if (!f)
- - {
- - DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- - return;
- - }
- -
- - for (d = subnetlist; d ; d = d->next)
- - {
- - struct work_record *work;
- - for (work = d->workgrouplist; work ; work = work->next)
- - {
- - struct server_record *s;
- - for (s = work->serverlist; s ; s = s->next)
- - {
- - fstring tmp;
- -
- - /* don't list domains I don't have a master for */
- - if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
- - !s->serv.comment[0])
- - {
- - continue;
- - }
- -
- - /* output server details, plus what workgroup/domain
- - they're in. without the domain information, the
- - combined list of all servers in all workgroups gets
- - sent to anyone asking about any workgroup! */
- -
- - sprintf(tmp, "\"%s\"", s->serv.name);
- - fprintf(f, "%-25s ", tmp);
- - fprintf(f, "%08x ", s->serv.type);
- - sprintf(tmp, "\"%s\" ", s->serv.comment);
- - fprintf(f, "%-30s", tmp);
- - fprintf(f, "\"%s\"\n", work->work_group);
- - }
- - }
- - }
- -
- - fclose(f);
- - unlink(fname);
- - chmod(fnamenew,0644);
- - rename(fnamenew,fname);
- - DEBUG(3,("Wrote browse list %s\n",fname));
- -}
- -
- -
- -/*******************************************************************
- - expire old servers in the serverlist
- - ******************************************************************/
- -void expire_servers(time_t t)
- -{
- - struct subnet_record *d;
- -
- - for (d = subnetlist ; d ; d = d->next)
- - {
- - struct work_record *work;
- -
- - for (work = d->workgrouplist; work; work = work->next)
- - {
- - remove_old_servers(work, t);
- - }
- - }
- -}
- -
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbname.c samba-1.9.16alpha11/source/namedbname.c
- --- samba-1.9.16alpha10/source/namedbname.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbname.c Thu Jul 18 20:53:15 1996
- @@ -0,0 +1,548 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Module name: namedbname.c
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 04 jul 96: lkcl@pires.co.uk
- + created module namedbname containing name database functions
- +*/
- +
- +#include "includes.h"
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring scope;
- +extern struct in_addr ipzero;
- +extern struct in_addr ipgrp;
- +
- +extern struct subnet_record *subnetlist;
- +
- +#define WINS_LIST "wins.dat"
- +
- +
- +/****************************************************************************
- + true if two netbios names are equal
- +****************************************************************************/
- +BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
- +{
- + return n1->name_type == n2->name_type &&
- + strequal(n1->name ,n2->name ) &&
- + strequal(n1->scope,n2->scope);
- +}
- +
- +
- +/****************************************************************************
- + true if the netbios name is ^1^2__MSBROWSE__^2^1
- +
- + note: this name is registered if as a master browser or backup browser
- + you are responsible for a workgroup (when you announce a domain by
- + broadcasting on your local subnet, you announce it as coming from this
- + name: see announce_host()).
- +
- + **************************************************************************/
- +BOOL ms_browser_name(char *name, int type)
- +{
- + return strequal(name,MSBROWSE) && type == 0x01;
- +}
- +
- +
- +/****************************************************************************
- + add a netbios name into the namelist
- + **************************************************************************/
- +static void add_name(struct subnet_record *d, struct name_record *n)
- +{
- + struct name_record *n2;
- +
- + if (!d) return;
- +
- + if (!d->namelist)
- + {
- + d->namelist = n;
- + n->prev = NULL;
- + n->next = NULL;
- + return;
- + }
- +
- + for (n2 = d->namelist; n2->next; n2 = n2->next) ;
- +
- + n2->next = n;
- + n->next = NULL;
- + n->prev = n2;
- +}
- +
- +
- +/****************************************************************************
- + remove a name from the namelist. The pointer must be an element just
- + retrieved
- + **************************************************************************/
- +void remove_name(struct subnet_record *d, struct name_record *n)
- +{
- + struct name_record *nlist;
- + if (!d) return;
- +
- + nlist = d->namelist;
- +
- + while (nlist && nlist != n) nlist = nlist->next;
- +
- + if (nlist)
- + {
- + if (nlist->next) nlist->next->prev = nlist->prev;
- + if (nlist->prev) nlist->prev->next = nlist->next;
- + free(nlist);
- + }
- +}
- +
- +
- +/****************************************************************************
- + find a name in a namelist.
- + **************************************************************************/
- +struct name_record *find_name(struct name_record *n,
- + struct nmb_name *name,
- + int search)
- +{
- + struct name_record *ret;
- +
- + for (ret = n; ret; ret = ret->next)
- + {
- + if (name_equal(&ret->name,name))
- + {
- + /* self search: self names only */
- + if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
- + continue;
- +
- + return ret;
- + }
- + }
- + return NULL;
- +}
- +
- +
- +/****************************************************************************
- + find a name in the domain database namelist
- + search can be any of:
- + FIND_SELF - look exclusively for names the samba server has added for itself
- + FIND_LOCAL - look for names in the local subnet record.
- + FIND_WINS - look for names in the WINS record
- + **************************************************************************/
- +struct name_record *find_name_search(struct subnet_record **d,
- + struct nmb_name *name,
- + int search, struct in_addr ip)
- +{
- + if (d == NULL) return NULL; /* bad error! */
- +
- + if ((search & FIND_LOCAL) == FIND_LOCAL)
- + {
- + if (*d != NULL)
- + {
- + DEBUG(4,("find_name on local: %s %s search %x\n",
- + namestr(name),inet_ntoa(ip), search));
- + return find_name((*d)->namelist, name, search);
- + }
- + else
- + {
- + DEBUG(4,("local find_name_search with a NULL subnet pointer\n"));
- + return NULL;
- + }
- + }
- +
- + if ((search & FIND_WINS) != FIND_WINS) return NULL;
- +
- + if (*d == NULL)
- + {
- + /* find WINS subnet record */
- + *d = find_subnet(ipgrp);
- + }
- +
- + if (*d == NULL) return NULL;
- +
- + DEBUG(4,("find_name on WINS: %s %s search %x\n",
- + namestr(name),inet_ntoa(ip), search));
- + return find_name((*d)->namelist, name, search);
- +}
- +
- +
- +/****************************************************************************
- + dump a copy of the name table
- + **************************************************************************/
- +void dump_names(void)
- +{
- + struct name_record *n;
- + struct subnet_record *d;
- + fstring fname, fnamenew;
- + time_t t = time(NULL);
- +
- + FILE *f;
- +
- + strcpy(fname,lp_lockdir());
- + trim_string(fname,NULL,"/");
- + strcat(fname,"/");
- + strcat(fname,WINS_LIST);
- + strcpy(fnamenew,fname);
- + strcat(fnamenew,".");
- +
- + f = fopen(fnamenew,"w");
- +
- + if (!f)
- + {
- + DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- + }
- +
- + DEBUG(3,("Dump of local name table:\n"));
- +
- + for (d = subnetlist; d; d = d->next)
- + for (n = d->namelist; n; n = n->next)
- + {
- + if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
- + {
- + fstring data;
- +
- + /* XXXX i have little imagination as to how to output nb_flags as
- + anything other than as a hexadecimal number :-) */
- +
- + sprintf(data, "%s#%02x %s %2x %ld",
- + n->name.name,n->name.name_type, /* XXXX ignore the scope for now */
- + inet_ntoa(n->ip),
- + n->nb_flags,
- + n->death_time);
- + fprintf(f, "%s\n", data);
- + }
- +
- + DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
- + DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
- + DEBUG(3,("%-19s %15s NB=%2x TTL=%ld \n",
- + namestr(&n->name),
- + inet_ntoa(n->ip),
- + n->nb_flags,
- + n->death_time?n->death_time-t:0));
- + }
- +
- + fclose(f);
- + unlink(fname);
- + chmod(fnamenew,0644);
- + rename(fnamenew,fname);
- +
- + DEBUG(3,("Wrote wins database %s\n",fname));
- +}
- +
- +
- +/****************************************************************************
- +load a netbios name database file
- +****************************************************************************/
- +void load_netbios_names(void)
- +{
- + struct subnet_record *d = find_subnet(ipgrp);
- + fstring fname;
- +
- + FILE *f;
- + pstring line;
- +
- + if (!d) return;
- +
- + strcpy(fname,lp_lockdir());
- + trim_string(fname,NULL,"/");
- + strcat(fname,"/");
- + strcat(fname,WINS_LIST);
- +
- + f = fopen(fname,"r");
- +
- + if (!f) {
- + DEBUG(2,("Can't open wins database file %s\n",fname));
- + return;
- + }
- +
- + while (!feof(f))
- + {
- + pstring name_str, ip_str, ttd_str, nb_flags_str;
- +
- + pstring name;
- + int type = 0;
- + int nb_flags;
- + time_t ttd;
- + struct in_addr ipaddr;
- +
- + enum name_source source;
- +
- + char *ptr;
- + int count = 0;
- +
- + char *p;
- +
- + if (!fgets_slash(line,sizeof(pstring),f)) continue;
- +
- + if (*line == '#') continue;
- +
- + ptr = line;
- +
- + if (next_token(&ptr,name_str ,NULL)) ++count;
- + if (next_token(&ptr,ip_str ,NULL)) ++count;
- + if (next_token(&ptr,ttd_str ,NULL)) ++count;
- + if (next_token(&ptr,nb_flags_str,NULL)) ++count;
- +
- + if (count <= 0) continue;
- +
- + if (count != 4) {
- + DEBUG(0,("Ill formed wins line"));
- + DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line));
- + continue;
- + }
- +
- + /* netbios name. # divides the name from the type (hex): netbios#xx */
- + strcpy(name,name_str);
- +
- + p = strchr(name,'#');
- +
- + if (p) {
- + *p = 0;
- + sscanf(p+1,"%x",&type);
- + }
- +
- + /* decode the netbios flags (hex) and the time-to-die (seconds) */
- + sscanf(nb_flags_str,"%x",&nb_flags);
- + sscanf(ttd_str,"%ld",&ttd);
- +
- + ipaddr = *interpret_addr2(ip_str);
- +
- + if (ip_equal(ipaddr,ipzero)) {
- + source = SELF;
- + }
- + else
- + {
- + source = REGISTER;
- + }
- +
- + DEBUG(4, ("add WINS line: %s#%02x %s %ld %2x\n",
- + name,type, inet_ntoa(ipaddr), ttd, nb_flags));
- +
- + /* add all entries that have 60 seconds or more to live */
- + if (ttd - 60 < time(NULL) || ttd == 0)
- + {
- + time_t t = (ttd?ttd-time(NULL):0) / 3;
- +
- + /* add netbios entry read from the wins.dat file. IF it's ok */
- + add_netbios_entry(d,name,type,nb_flags,t,source,ipaddr,True,True);
- + }
- + }
- +
- + fclose(f);
- +}
- +
- +
- +/****************************************************************************
- + remove an entry from the name list
- + ****************************************************************************/
- +void remove_netbios_name(struct subnet_record *d,
- + char *name,int type, enum name_source source,
- + struct in_addr ip)
- +{
- + struct nmb_name nn;
- + struct name_record *n;
- +
- + make_nmb_name(&nn, name, type, scope);
- + n = find_name_search(&d, &nn, FIND_LOCAL, ip);
- +
- + if (n && n->source == source) remove_name(d,n);
- +}
- +
- +
- +/****************************************************************************
- + add an entry to the name list.
- +
- + this is a multi-purpose function.
- +
- + it adds samba's own names in to its records on each interface, keeping a
- + record of whether it is a master browser, domain master, or WINS server.
- +
- + it also keeps a record of WINS entries.
- +
- + ****************************************************************************/
- +struct name_record *add_netbios_entry(struct subnet_record *d,
- + char *name, int type, int nb_flags,
- + int ttl, enum name_source source, struct in_addr ip,
- + BOOL new_only,BOOL wins)
- +{
- + struct name_record *n;
- + struct name_record *n2=NULL;
- + int search = 0;
- + BOOL self = source == SELF;
- +
- + /* add the name to the WINS list if the name comes from a directed query */
- + search |= wins ? FIND_WINS : FIND_LOCAL;
- + /* search for SELF names only */
- + search |= self ? FIND_SELF : 0;
- +
- + if (!self)
- + {
- + if (!wins && type != 0x1b)
- + {
- + /* the only broadcast (non-WINS) names we are adding are ours
- + (SELF) and PDC type names */
- + return NULL;
- + }
- + }
- +
- + n = (struct name_record *)malloc(sizeof(*n));
- + if (!n) return(NULL);
- +
- + bzero((char *)n,sizeof(*n));
- +
- + make_nmb_name(&n->name,name,type,scope);
- +
- + if ((n2 = find_name_search(&d, &n->name, search, new_only?ipzero:ip)))
- + {
- + free(n);
- + if (new_only || (n2->source==SELF && source!=SELF)) return n2;
- + n = n2;
- + }
- +
- + if (ttl)
- + n->death_time = time(NULL)+ttl*3;
- + n->refresh_time = time(NULL)+GET_TTL(ttl);
- +
- + n->ip = ip;
- + n->nb_flags = nb_flags;
- + n->source = source;
- +
- + if (!n2) add_name(d,n);
- +
- + DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
- + namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
- +
- + return(n);
- +}
- +
- +
- +/*******************************************************************
- + expires old names in the namelist
- + ******************************************************************/
- +void expire_names(time_t t)
- +{
- + struct name_record *n;
- + struct name_record *next;
- + struct subnet_record *d;
- +
- + /* expire old names */
- + for (d = subnetlist; d; d = d->next)
- + {
- + for (n = d->namelist; n; n = next)
- + {
- + if (n->death_time && n->death_time < t)
- + {
- + DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
- +
- + next = n->next;
- +
- + if (n->prev) n->prev->next = n->next;
- + if (n->next) n->next->prev = n->prev;
- +
- + if (d->namelist == n) d->namelist = n->next;
- +
- + free(n);
- + }
- + else
- + {
- + next = n->next;
- + }
- + }
- + }
- +}
- +
- +
- +/***************************************************************************
- + reply to a name query
- + ****************************************************************************/
- +struct name_record *search_for_name(struct subnet_record **d,
- + struct nmb_name *question,
- + struct in_addr ip, int Time, int search)
- +{
- + int name_type = question->name_type;
- + char *qname = question->name;
- + BOOL dns_type = name_type == 0x20 || name_type == 0;
- +
- + struct name_record *n;
- +
- + DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
- +
- + /* first look up name in cache */
- + n = find_name_search(d,question,search,ip);
- +
- + if (*d == NULL) return NULL;
- +
- + DEBUG(4,("subnet %s ", inet_ntoa((*d)->bcast_ip)));
- +
- + /* now try DNS lookup. */
- + if (!n)
- + {
- + struct in_addr dns_ip;
- + unsigned long a;
- +
- + /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
- + if (!dns_type && name_type != 0x1b)
- + {
- + DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
- + return NULL;
- + }
- +
- + /* look it up with DNS */
- + a = interpret_addr(qname);
- +
- + putip((char *)&dns_ip,(char *)&a);
- +
- + if (!a)
- + {
- + /* no luck with DNS. We could possibly recurse here XXXX */
- + DEBUG(3,("no recursion.\n"));
- + /* add the fail to our WINS cache of names. give it 1 hour in the cache */
- + add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
- + True, True);
- + return NULL;
- + }
- +
- + /* add it to our WINS cache of names. give it 2 hours in the cache */
- + n = add_netbios_entry(*d,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
- + True,True);
- +
- + /* failed to add it? yikes! */
- + if (!n) return NULL;
- + }
- +
- + /* is our entry already dead? */
- + if (n->death_time)
- + {
- + if (n->death_time < Time) return False;
- + }
- +
- + /* it may have been an earlier failure */
- + if (n->source == DNSFAIL)
- + {
- + DEBUG(3,("DNSFAIL\n"));
- + return NULL;
- + }
- +
- + DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));
- +
- + return n;
- +}
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbname.doc samba-1.9.16alpha11/source/namedbname.doc
- --- samba-1.9.16alpha10/source/namedbname.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbname.doc Sun Jul 7 22:35:55 1996
- @@ -0,0 +1,155 @@
- +this module deals with the NetBIOS name database for samba. it deals
- +directly with adding, removing, finding, loading and saving of names.
- +
- +/*************************************************************************
- + search_for_name()
- + *************************************************************************/
- +
- +this function is responsible for finding a name in the appropriate part
- +of samba's NetBIOS name database. if the name cannot be found, then it
- +should look the name up using DNS. later modifications will be to
- +forward the request on to another WINS server, should samba not be able
- +to find out about the requested name (this will be implemented through
- +issuing a new type of samba 'state').
- +
- +the name is first searched for in the NetBIOS cache. if it cannot be
- +found, then it if the name looks like it's a server-type name (0x20
- +0x0 or 0x1b) then DNS is used to look for the name.
- +
- +if DNS fails, then a record of this failure is kept. if it succeeds, then
- +a new NetBIOS entry is added.
- +
- +the successfully found name is returned. on failure, NULL is returned.
- +
- +
- +/*************************************************************************
- + expire_names()
- + *************************************************************************/
- +
- +this function is responsible for removing old NetBIOS names from its
- +database. no further action is required.
- +
- +for over-zealous WINS systems, the use of query_refresh_names() is
- +recommended. this function initiates polling of hosts that have
- +registered with samba in its capacity as a WINS server. an alternative
- +means to achieve the same end as query_refresh_names() is to
- +reduce the time to live when the name is registered with samba,
- +except that in this instance the responsibility for refreshing the
- +name is with the owner of the name, not the server with which the name
- +is registered.
- +
- +
- +/*************************************************************************
- + add_netbios_entry()
- + *************************************************************************/
- +
- +this function is responsible for adding or updating a NetBIOS name
- +in the database. into the local interface records, the only names
- +that will be added are those of primary domain controllers and
- +samba's own names. into the WINS records, all names are added.
- +
- +the name to be added / updated will be looked up in the records.
- +if it is found, then we will not overwrite the entry if the flag
- +'newonly' is True, or if the name is being added as a non-SELF
- +(non-samba) name and the records indicate that samba owns the
- +name.
- +
- +otherwise, the name is added or updated with the new details.
- +
- +
- +/*************************************************************************
- + remove_netbios_entry()
- + *************************************************************************/
- +
- +this function is responsible for removing a NetBIOS entry from
- +the database. the name is searched for in the records using
- +find_name_search(). if the ip is zero, then the ip is ignored.
- +
- +the name is removed if the expected source (e.g SELF, REGISTER)
- +matches that in the database.
- +
- +
- +/*************************************************************************
- + load_netbios_names()
- + *************************************************************************/
- +
- +this function is responsible for loading any NetBIOS names that samba,
- +in its WINS capacity, has written out to disk. all the relevant details
- +are recorded in this file, including the time-to-live. should the
- +time left to live be small, the name is not added back in to samba's
- +WINS database.
- +
- +
- +/*************************************************************************
- + dump_names()
- + *************************************************************************/
- +
- +this function is responsible for outputting NetBIOS names in two formats.
- +firstly, as debugging information, and secondly, all names that have been
- +registered with samba in its capacity as a WINS server are written to
- +disk.
- +
- +writing all WINS names allows two things. firstly, if samba's NetBIOS
- +daemon dies or is terminated, on restarting the daemon most if not all
- +of the registered WINS names will be preserved (which is a good reason
- +why query_netbios_names() should be used).
- +
- +
- +/*************************************************************************
- + find_name_search()
- + *************************************************************************/
- +
- +this function is a wrapper around find_name(). find_name_search() can
- +be told whether to search for the name in a local subnet structure or
- +in the WINS database. on top of this, it can be told to search only
- +for samba's SELF names.
- +
- +if it finds the name in the WINS database, it will set the subnet_record
- +and also return the name it finds.
- +
- +
- +/*************************************************************************
- + find_name()
- + *************************************************************************/
- +
- +this function is a low-level search function that searches a single
- +interface's NetBIOS records for a name. if the ip to be found is
- +zero then the ip address is ignored. this is to enable a name to
- +be found without knowing its ip address, and also to find the exact
- +name if a large number of group names are added with different ip
- +addresses.
- +
- +
- +/*************************************************************************
- + remove_name()
- + *************************************************************************/
- +
- +this function is responsible for removing a specific NetBIOS entry
- +from a subnet list's records. only if the pointer to the entry is
- +in the list will the name be removed.
- +
- +
- +/*************************************************************************
- + add_name()
- + *************************************************************************/
- +
- +this function is responsible for adding a NetBIOS entry into a
- +subnet list's records.
- +
- +
- +/*************************************************************************
- + ms_browser_name()
- + *************************************************************************/
- +
- +this function returns True if the NetBIOS name passed to it is
- +^1^2__MSBROWSE__^2^1
- +
- +
- +/*************************************************************************
- + name_equal()
- + *************************************************************************/
- +
- +this function returns True if the two NetBIOS names passed to it
- +match in name, type and scope: the NetBIOS names are equal.
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbresp.c samba-1.9.16alpha11/source/namedbresp.c
- --- samba-1.9.16alpha10/source/namedbresp.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbresp.c Wed Jul 10 04:01:24 1996
- @@ -0,0 +1,156 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios library routines
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Module name: namedbresp.c
- +
- +*/
- +
- +#include "includes.h"
- +
- +extern int ClientNMB;
- +extern int ClientDGRAM;
- +
- +extern struct subnet_record *subnetlist;
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring scope;
- +extern pstring myname;
- +extern struct in_addr ipzero;
- +extern struct in_addr ipgrp;
- +
- +int num_response_packets = 0;
- +
- +/***************************************************************************
- + add an expected response record into the list
- + **************************************************************************/
- +void add_response_record(struct subnet_record *d,
- + struct response_record *n)
- +{
- + struct response_record *n2;
- +
- + if (!d) return;
- +
- + num_response_packets++; /* count of total number of packets still around */
- +
- + DEBUG(4,("adding response record id:%d num_records:%d\n",
- + n->response_id, num_response_packets));
- +
- + if (!d->responselist)
- + {
- + d->responselist = n;
- + n->prev = NULL;
- + n->next = NULL;
- + return;
- + }
- +
- + for (n2 = d->responselist; n2->next; n2 = n2->next) ;
- +
- + n2->next = n;
- + n->next = NULL;
- + n->prev = n2;
- +}
- +
- +
- +/***************************************************************************
- + remove an expected response record from the list
- + **************************************************************************/
- +void remove_response_record(struct subnet_record *d,
- + struct response_record *n)
- +{
- + if (!d) return;
- +
- + if (n->prev) n->prev->next = n->next;
- + if (n->next) n->next->prev = n->prev;
- +
- + if (d->responselist == n) d->responselist = n->next;
- +
- + free(n);
- +
- + num_response_packets--; /* count of total number of packets still around */
- +}
- +
- +
- +/****************************************************************************
- + create a name query response record
- + **************************************************************************/
- +struct response_record *make_response_queue_record(enum state_type state,
- + int id,uint16 fd,
- + int quest_type, char *name,int type, int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip)
- +{
- + struct response_record *n;
- +
- + if (!name || !name[0]) return NULL;
- +
- + if (!(n = (struct response_record *)malloc(sizeof(*n))))
- + return(NULL);
- +
- + n->response_id = id;
- + n->state = state;
- + n->fd = fd;
- + n->quest_type = quest_type;
- + make_nmb_name(&n->name, name, type, scope);
- + n->nb_flags = nb_flags;
- + n->ttl = ttl;
- + n->bcast = bcast;
- + n->recurse = recurse;
- + n->send_ip = send_ip;
- + n->reply_to_ip = reply_to_ip;
- +
- + n->repeat_interval = 1; /* XXXX should be in ms */
- + n->repeat_count = 3; /* 3 retries */
- + n->repeat_time = time(NULL) + n->repeat_interval; /* initial retry time */
- +
- + n->num_msgs = 0;
- +
- + return n;
- +}
- +
- +
- +/****************************************************************************
- + find a response in a subnet's name query response list.
- + **************************************************************************/
- +struct response_record *find_response_record(struct subnet_record **d,
- + uint16 id)
- +{
- + struct response_record *n;
- +
- + if (!d) return NULL;
- +
- + for ((*d) = subnetlist; (*d); (*d) = (*d)->next)
- + {
- + for (n = (*d)->responselist; n; n = n->next)
- + {
- + if (n->response_id == id) {
- + DEBUG(4, ("found response record on %s: %d\n",
- + inet_ntoa((*d)->bcast_ip), id));
- + return n;
- + }
- + }
- + }
- +
- + *d = NULL;
- +
- + return NULL;
- +}
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbresp.doc samba-1.9.16alpha11/source/namedbresp.doc
- --- samba-1.9.16alpha10/source/namedbresp.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbresp.doc Thu Jul 11 04:48:26 1996
- @@ -0,0 +1,48 @@
- +module namedbresp deals with the maintenance of the list of expected
- +responses - creating, finding and removal.
- +
- +module nameresp deals with the initial transmission, re-transmission
- +and time-out of netbios response records.
- +
- +
- +/*************************************************************************
- + find_response_record()
- + *************************************************************************/
- +
- +this function is responsible for matching the unique response transaction
- +id with an expected response record. as a side-effect of this search,
- +it will find the subnet (or the WINS pseudo-subnet) that samba expected
- +the response to come from.
- +
- +
- +/*************************************************************************
- + make_response_queue_record()
- + *************************************************************************/
- +
- +this function is responsible for creating a response record, which will
- +be queued awaiting a response.
- +
- +the number of retries is set to 3, and the retry period set to 1 second.
- +if no response is received, then the packet is re-transmitted, which is
- +why so much information is stored in the response record.
- +
- +the number of expected responses queued is kept, so listen_for_packets()
- +knows it must time-out after 1 second if one or more responses are
- +expected.
- +
- +
- +/*************************************************************************
- + remove_response_record()
- + *************************************************************************/
- +
- +this function is responsible for removing a response record from the
- +expected response queue. the number of expected responses is decreased.
- +
- +
- +/*************************************************************************
- + add_response_record()
- + *************************************************************************/
- +
- +this function is responsible for adding the response record created by
- +make_response_queue_record() into the appropriate response record queue.
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbserver.c samba-1.9.16alpha11/source/namedbserver.c
- --- samba-1.9.16alpha10/source/namedbserver.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbserver.c Thu Jul 18 20:53:15 1996
- @@ -0,0 +1,221 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 04 jul 96: lkcl@pires.co.uk
- + created module namedbserver containing server database functions
- +
- +*/
- +
- +#include "includes.h"
- +#include "smb.h"
- +
- +extern int ClientNMB;
- +extern int ClientDGRAM;
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring myname;
- +
- +/* this is our domain/workgroup/server database */
- +extern struct subnet_record *subnetlist;
- +
- +extern BOOL updatedlists;
- +
- +
- +/*******************************************************************
- + expire old servers in the serverlist
- + time of -1 indicates everybody dies except those with time of 0
- + remove_all_servers indicates everybody dies.
- + ******************************************************************/
- +void remove_old_servers(struct work_record *work, time_t t,
- + BOOL remove_all)
- +{
- + struct server_record *s;
- + struct server_record *nexts;
- +
- + /* expire old entries in the serverlist */
- + for (s = work->serverlist; s; s = nexts)
- + {
- + if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
- + {
- + DEBUG(3,("Removing dead server %s\n",s->serv.name));
- + updatedlists = True;
- + nexts = s->next;
- +
- + if (s->prev) s->prev->next = s->next;
- + if (s->next) s->next->prev = s->prev;
- +
- + if (work->serverlist == s)
- + work->serverlist = s->next;
- +
- + free(s);
- + }
- + else
- + {
- + nexts = s->next;
- + }
- + }
- +}
- +
- +
- +/***************************************************************************
- + add a server into the list
- + **************************************************************************/
- +static void add_server(struct work_record *work,struct server_record *s)
- +{
- + struct server_record *s2;
- +
- + if (!work->serverlist) {
- + work->serverlist = s;
- + s->prev = NULL;
- + s->next = NULL;
- + return;
- + }
- +
- + for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
- +
- + s2->next = s;
- + s->next = NULL;
- + s->prev = s2;
- +}
- +
- +
- +/****************************************************************************
- + find a server in a server list.
- + **************************************************************************/
- +struct server_record *find_server(struct work_record *work, char *name)
- +{
- + struct server_record *ret;
- +
- + if (!work) return NULL;
- +
- + for (ret = work->serverlist; ret; ret = ret->next)
- + {
- + if (strequal(ret->serv.name,name))
- + {
- + return ret;
- + }
- + }
- + return NULL;
- +}
- +
- +
- +/****************************************************************************
- + add a server entry
- + ****************************************************************************/
- +struct server_record *add_server_entry(struct subnet_record *d,
- + struct work_record *work,
- + char *name,int servertype,
- + int ttl,char *comment,
- + BOOL replace)
- +{
- + BOOL newentry=False;
- + struct server_record *s;
- +
- + if (name[0] == '*')
- + {
- + return (NULL);
- + }
- +
- + s = find_server(work, name);
- +
- + if (s && !replace)
- + {
- + DEBUG(4,("Not replacing %s\n",name));
- + return(s);
- + }
- +
- + if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
- + updatedlists=True;
- +
- + if (!s)
- + {
- + newentry = True;
- + s = (struct server_record *)malloc(sizeof(*s));
- +
- + if (!s) return(NULL);
- +
- + bzero((char *)s,sizeof(*s));
- + }
- +
- +
- + if (d->my_interface && strequal(lp_workgroup(),work->work_group))
- + {
- + if (servertype)
- + servertype |= SV_TYPE_LOCAL_LIST_ONLY;
- + }
- + else
- + {
- + servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
- + }
- +
- + /* update the entry */
- + StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
- + StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
- + strupper(s->serv.name);
- + s->serv.type = servertype;
- + s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
- +
- + /* for a domain entry, the comment field refers to the server name */
- +
- + if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
- +
- + if (newentry)
- + {
- + add_server(work, s);
- +
- + DEBUG(3,("Added "));
- + }
- + else
- + {
- + DEBUG(3,("Updated "));
- + }
- +
- + DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
- + name,servertype,comment,
- + work->work_group,inet_ntoa(d->bcast_ip)));
- +
- + return(s);
- +}
- +
- +
- +/*******************************************************************
- + expire old servers in the serverlist
- + ******************************************************************/
- +void expire_servers(time_t t)
- +{
- + struct subnet_record *d;
- +
- + for (d = subnetlist ; d ; d = d->next)
- + {
- + struct work_record *work;
- +
- + for (work = d->workgrouplist; work; work = work->next)
- + {
- + remove_old_servers(work, t, False);
- + }
- + }
- +}
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbsubnet.c samba-1.9.16alpha11/source/namedbsubnet.c
- --- samba-1.9.16alpha10/source/namedbsubnet.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbsubnet.c Thu Jul 11 04:48:26 1996
- @@ -0,0 +1,346 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 04 jul 96: lkcl@pires.co.uk
- + created module namedbsubnet containing subnet database functions
- +
- +*/
- +
- +#include "includes.h"
- +#include "smb.h"
- +
- +extern int ClientNMB;
- +extern int ClientDGRAM;
- +
- +extern int DEBUGLEVEL;
- +
- +extern struct in_addr ipgrp;
- +extern struct in_addr ipzero;
- +
- +extern pstring myname;
- +
- +BOOL updatedlists = True;
- +int updatecount = 0;
- +
- +/* local interfaces structure */
- +extern struct interface *local_interfaces;
- +
- +/* remote interfaces structure */
- +extern struct interface *remote_interfaces;
- +
- +/* this is our domain/workgroup/server database */
- +struct subnet_record *subnetlist = NULL;
- +
- +
- +/****************************************************************************
- + add a domain into the list
- + **************************************************************************/
- +static void add_subnet(struct subnet_record *d)
- +{
- + struct subnet_record *d2;
- +
- + if (!subnetlist)
- + {
- + subnetlist = d;
- + d->prev = NULL;
- + d->next = NULL;
- + return;
- + }
- +
- + for (d2 = subnetlist; d2->next; d2 = d2->next);
- +
- + d2->next = d;
- + d->next = NULL;
- + d->prev = d2;
- +}
- +
- +
- +/****************************************************************************
- + find a subnet in the subnetlist
- + **************************************************************************/
- +struct subnet_record *find_subnet(struct in_addr bcast_ip)
- +{
- + struct subnet_record *d;
- + struct in_addr wins_ip = ipgrp;
- +
- + /* search through subnet list for broadcast/netmask that matches
- + the source ip address. a subnet 255.255.255.255 represents the
- + WINS list. */
- +
- + for (d = subnetlist; d; d = d->next)
- + {
- + if (ip_equal(bcast_ip, wins_ip))
- + {
- + if (ip_equal(bcast_ip, d->bcast_ip))
- + {
- + return d;
- + }
- + }
- + else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
- + {
- + return(d);
- + }
- + }
- +
- + return (NULL);
- +}
- +
- +
- +/****************************************************************************
- + finds the appropriate subnet structure. directed packets (non-bcast) are
- + assumed to come from a point-to-point (P or M node), and so the subnet we
- + return in this instance is the WINS 'pseudo-subnet' with ip 255.255.255.255
- + ****************************************************************************/
- +struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
- +{
- + if (bcast)
- + {
- + /* identify the subnet the broadcast request came from */
- + return find_subnet(*iface_bcast(ip));
- + }
- + /* find the subnet under the pseudo-ip of 255.255.255.255 */
- + return find_subnet(ipgrp);
- +}
- +
- +
- +/****************************************************************************
- + create a domain entry
- + ****************************************************************************/
- +static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr mask_ip)
- +{
- + struct subnet_record *d;
- + d = (struct subnet_record *)malloc(sizeof(*d));
- +
- + if (!d) return(NULL);
- +
- + bzero((char *)d,sizeof(*d));
- +
- + DEBUG(4, ("making domain %s ", inet_ntoa(bcast_ip)));
- + DEBUG(4, ("%s\n", inet_ntoa(mask_ip)));
- +
- + d->bcast_ip = bcast_ip;
- + d->mask_ip = mask_ip;
- + d->workgrouplist = NULL;
- + d->my_interface = False; /* True iff the interface is on the samba host */
- +
- + add_subnet(d);
- +
- + return d;
- +}
- +
- +
- +/****************************************************************************
- + add the remote interfaces from lp_remote_interfaces() and lp_interfaces()
- + to the netbios subnet database.
- + ****************************************************************************/
- +void add_subnet_interfaces(void)
- +{
- + struct interface *i;
- +
- + /* loop on all local interfaces */
- + for (i = local_interfaces; i; i = i->next)
- + {
- + /* add the interface into our subnet database */
- + if (!find_subnet(i->bcast))
- + {
- + struct subnet_record *d = make_subnet(i->bcast,i->nmask);
- + if (d)
- + {
- + /* short-cut method to identifying local interfaces */
- + d->my_interface = True;
- + }
- + }
- + }
- +
- + /* loop on all remote interfaces */
- + for (i = remote_interfaces; i; i = i->next)
- + {
- + /* add the interface into our subnet database */
- + if (!find_subnet(i->bcast))
- + {
- + make_subnet(i->bcast,i->nmask);
- + }
- + }
- +
- + /* add the pseudo-ip interface for WINS: 255.255.255.255 */
- + if (lp_wins_support())
- + {
- + struct in_addr wins_bcast = ipgrp;
- + struct in_addr wins_nmask = ipzero;
- + make_subnet(wins_bcast, wins_nmask);
- + }
- +}
- +
- +
- +
- +/****************************************************************************
- + add the default workgroup into my domain
- + **************************************************************************/
- +void add_my_subnets(char *group)
- +{
- + struct interface *i;
- +
- + /* add or find domain on our local subnet, in the default workgroup */
- +
- + if (*group == '*') return;
- +
- + /* the coding choice is up to you, andrew: i can see why you don't want
- + global access to the local_interfaces structure: so it can't get
- + messed up! */
- + for (i = local_interfaces; i; i = i->next)
- + {
- + add_subnet_entry(i->bcast,i->nmask,group, True, False);
- + }
- +}
- +
- +
- +/****************************************************************************
- + add a domain entry. creates a workgroup, if necessary, and adds the domain
- + to the named a workgroup.
- + ****************************************************************************/
- +struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
- + struct in_addr mask_ip,
- + char *name, BOOL add, BOOL lmhosts)
- +{
- + struct subnet_record *d;
- +
- + /* XXXX andrew: struct in_addr ip appears not to be referenced at all except
- + in the DEBUG comment. i assume that the DEBUG comment below actually
- + intends to refer to bcast_ip? i don't know.
- +
- + struct in_addr ip = ipgrp;
- +
- + */
- +
- + if (zero_ip(bcast_ip))
- + bcast_ip = *iface_bcast(bcast_ip);
- +
- + /* add the domain into our domain database */
- + if ((d = find_subnet(bcast_ip)) ||
- + (d = make_subnet(bcast_ip, mask_ip)))
- + {
- + struct work_record *w = find_workgroupstruct(d, name, add);
- + extern pstring ServerComment;
- +
- + if (!w) return NULL;
- +
- + /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
- + or register with WINS server, if it's our workgroup */
- + if (strequal(lp_workgroup(), name) && d->my_interface)
- + {
- + add_my_name_entry(d,name,0x1e,NB_ACTIVE|NB_GROUP);
- + add_my_name_entry(d,name,0x0 ,NB_ACTIVE|NB_GROUP);
- + }
- + /* add samba server name to workgroup list. don't add
- + lmhosts server entries to local interfaces */
- + if ((strequal(lp_workgroup(), name) && d->my_interface) ||
- + (lmhosts && !d->my_interface))
- + {
- + add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
- + DEBUG(3,("Added server name entry %s at %s\n",
- + name,inet_ntoa(bcast_ip)));
- + }
- +
- + return d;
- + }
- + return NULL;
- +}
- +
- +
- +/*******************************************************************
- + write out browse.dat
- + ******************************************************************/
- +void write_browse_list(void)
- +{
- + struct subnet_record *d;
- + pstring fname,fnamenew;
- + FILE *f;
- +
- + static time_t lasttime = 0;
- + time_t t = time(NULL);
- +
- + if (!lasttime) lasttime = t;
- + if (!updatedlists || t - lasttime < 5) return;
- +
- + lasttime = t;
- + updatedlists = False;
- + updatecount++;
- +
- + dump_names();
- + dump_workgroups();
- +
- + strcpy(fname,lp_lockdir());
- + trim_string(fname,NULL,"/");
- + strcat(fname,"/");
- + strcat(fname,SERVER_LIST);
- + strcpy(fnamenew,fname);
- + strcat(fnamenew,".");
- +
- + f = fopen(fnamenew,"w");
- +
- + if (!f)
- + {
- + DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- + return;
- + }
- +
- + for (d = subnetlist; d ; d = d->next)
- + {
- + struct work_record *work;
- + for (work = d->workgrouplist; work ; work = work->next)
- + {
- + struct server_record *s;
- + for (s = work->serverlist; s ; s = s->next)
- + {
- + fstring tmp;
- +
- + /* don't list domains I don't have a master for */
- + if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
- + {
- + continue;
- + }
- +
- + /* output server details, plus what workgroup/domain
- + they're in. without the domain information, the
- + combined list of all servers in all workgroups gets
- + sent to anyone asking about any workgroup! */
- +
- + sprintf(tmp, "\"%s\"", s->serv.name);
- + fprintf(f, "%-25s ", tmp);
- + fprintf(f, "%08x ", s->serv.type);
- + sprintf(tmp, "\"%s\" ", s->serv.comment);
- + fprintf(f, "%-30s", tmp);
- + fprintf(f, "\"%s\"\n", work->work_group);
- + }
- + }
- + }
- +
- + fclose(f);
- + unlink(fname);
- + chmod(fnamenew,0644);
- + rename(fnamenew,fname);
- + DEBUG(3,("Wrote browse list %s\n",fname));
- +}
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbwork.c samba-1.9.16alpha11/source/namedbwork.c
- --- samba-1.9.16alpha10/source/namedbwork.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namedbwork.c Wed Jul 10 04:01:25 1996
- @@ -0,0 +1,255 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 04 jul 96: lkcl@pires.co.uk
- + created module namedbwork containing workgroup database functions
- +
- +*/
- +
- +#include "includes.h"
- +#include "smb.h"
- +
- +extern int ClientNMB;
- +
- +extern int DEBUGLEVEL;
- +
- +/* this is our domain/workgroup/server database */
- +extern struct subnet_record *subnetlist;
- +
- +int workgroup_count = 0; /* unique index key: one for each workgroup */
- +
- +/* what server type are we currently */
- +
- +#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
- + SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
- + SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
- +
- +
- +/****************************************************************************
- + add a workgroup into the domain list
- + **************************************************************************/
- +static void add_workgroup(struct work_record *work, struct subnet_record *d)
- +{
- + struct work_record *w2;
- +
- + if (!work || !d) return;
- +
- + if (!d->workgrouplist)
- + {
- + d->workgrouplist = work;
- + work->prev = NULL;
- + work->next = NULL;
- + return;
- + }
- +
- + for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
- +
- + w2->next = work;
- + work->next = NULL;
- + work->prev = w2;
- +}
- +
- +
- +/****************************************************************************
- + create a blank workgroup
- + **************************************************************************/
- +static struct work_record *make_workgroup(char *name)
- +{
- + struct work_record *work;
- + struct subnet_record *d;
- + int t = -1;
- +
- + if (!name || !name[0]) return NULL;
- +
- + work = (struct work_record *)malloc(sizeof(*work));
- + if (!work) return(NULL);
- +
- + StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- + work->serverlist = NULL;
- +
- + work->ServerType = DFLT_SERVER_TYPE;
- + work->RunningElection = False;
- + work->ElectionCount = 0;
- + work->needelection = False;
- + work->needannounce = True;
- + work->state = MST_NONE;
- +
- + /* make sure all token representations of workgroups are unique */
- +
- + for (d = subnetlist; d && t == -1; d = d->next)
- + {
- + struct work_record *w;
- + for (w = d->workgrouplist; w && t == -1; w = w->next)
- + {
- + if (strequal(w->work_group, work->work_group)) t = w->token;
- + }
- + }
- +
- + if (t == -1)
- + {
- + work->token = ++workgroup_count;
- + }
- + else
- + {
- + work->token = t;
- + }
- +
- +
- + /* WfWg uses 01040b01 */
- + /* Win95 uses 01041501 */
- + /* NTAS uses ???????? */
- + work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
- + work->ElectionCriterion |= (lp_os_level() << 24);
- + if (lp_domain_master()) {
- + work->ElectionCriterion |= 0x80;
- + }
- +
- + return work;
- +}
- +
- +
- +/*******************************************************************
- + remove workgroups
- + ******************************************************************/
- +struct work_record *remove_workgroup(struct subnet_record *d,
- + struct work_record *work,
- + BOOL remove_all_servers)
- +{
- + struct work_record *ret_work = NULL;
- +
- + if (!d || !work) return NULL;
- +
- + DEBUG(3,("Removing old workgroup %s\n", work->work_group));
- +
- + ret_work = work->next;
- +
- + remove_old_servers(work, -1, remove_all_servers);
- +
- + if (!work->serverlist)
- + {
- + if (work->prev) work->prev->next = work->next;
- + if (work->next) work->next->prev = work->prev;
- +
- + if (d->workgrouplist == work) d->workgrouplist = work->next;
- +
- + free(work);
- + }
- +
- + return ret_work;
- +}
- +
- +
- +/****************************************************************************
- + find a workgroup in the workgrouplist
- + only create it if the domain allows it, or the parameter 'add' insists
- + that it get created/added anyway. this allows us to force entries in
- + lmhosts file to be added.
- + **************************************************************************/
- +struct work_record *find_workgroupstruct(struct subnet_record *d,
- + fstring name, BOOL add)
- +{
- + struct work_record *ret, *work;
- +
- + if (!d) return NULL;
- +
- + DEBUG(4, ("workgroup search for %s: ", name));
- +
- + if (strequal(name, "*"))
- + {
- + DEBUG(2,("add any workgroups: initiating browser search on %s\n",
- + inet_ntoa(d->bcast_ip)));
- + queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
- + MSBROWSE,0x1,0,0,
- + True,False, d->bcast_ip, d->bcast_ip);
- + return NULL;
- + }
- +
- + for (ret = d->workgrouplist; ret; ret = ret->next) {
- + if (!strcmp(ret->work_group,name)) {
- + DEBUG(4, ("found\n"));
- + return(ret);
- + }
- + }
- +
- + if (!add) {
- + DEBUG(4, ("not found\n"));
- + return NULL;
- + }
- +
- + DEBUG(4,("not found: creating\n"));
- +
- + if ((work = make_workgroup(name)))
- + {
- + if (lp_preferred_master() &&
- + strequal(lp_workgroup(), name) &&
- + d->my_interface)
- + {
- + DEBUG(3, ("preferred master startup for %s\n", work->work_group));
- + work->needelection = True;
- + work->ElectionCriterion |= (1<<3);
- + }
- + if (!d->my_interface)
- + {
- + work->needelection = False;
- + }
- + add_workgroup(work, d);
- + return(work);
- + }
- + return NULL;
- +}
- +
- +
- +/****************************************************************************
- + dump a copy of the workgroup/domain database
- + **************************************************************************/
- +void dump_workgroups(void)
- +{
- + struct subnet_record *d;
- +
- + for (d = subnetlist; d; d = d->next)
- + {
- + if (d->workgrouplist)
- + {
- + struct work_record *work;
- +
- + DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
- + DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
- +
- + for (work = d->workgrouplist; work; work = work->next)
- + {
- + DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
- + if (work->serverlist)
- + {
- + struct server_record *s;
- + for (s = work->serverlist; s; s = s->next)
- + {
- + DEBUG(4,("\t\t%s %8x (%s)\n",
- + s->serv.name, s->serv.type, s->serv.comment));
- + }
- + }
- + }
- + }
- + }
- +}
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameelect.c samba-1.9.16alpha11/source/nameelect.c
- --- samba-1.9.16alpha10/source/nameelect.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/nameelect.c Thu Jul 18 20:53:15 1996
- @@ -2,7 +2,7 @@
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- - Copyright (C) Andrew Tridgell 1994-1995
- + Copyright (C) Andrew Tridgell 1994-1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- @@ -18,11 +18,17 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- + Module name: nameelect.c
- +
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- + 04 jul 96: lkcl@pires.co.uk
- + added system to become a master browser by stages.
- +
- +
- */
-
- #include "includes.h"
- @@ -34,6 +40,8 @@
- extern pstring scope;
-
- extern pstring myname;
- +extern struct in_addr ipzero;
- +extern struct in_addr ipgrp;
-
- /* machine comment for host announcements */
- extern pstring ServerComment;
- @@ -42,10 +50,6 @@
-
- extern time_t StartupTime;
-
- -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
- -
- -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
- -
- extern struct subnet_record *subnetlist;
-
-
- @@ -59,9 +63,8 @@
- struct subnet_record *d;
-
- if (!lastrun) lastrun = t;
- - if (t < lastrun + CHECK_TIME_MST_BROWSE * 60)
- + if (t < lastrun + CHECK_TIME_MST_BROWSE * 60)
- return;
- -
- lastrun = t;
-
- dump_workgroups();
- @@ -77,9 +80,9 @@
-
- if (!AM_MASTER(work))
- {
- - queue_netbios_packet(ClientNMB,NMB_QUERY,CHECK_MASTER,
- - work->work_group,0x1d,0,
- - True,False,d->bcast_ip);
- + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
- + work->work_group,0x1d,0,0,
- + True,False,d->bcast_ip,d->bcast_ip);
- }
- }
- }
- @@ -91,36 +94,38 @@
- ******************************************************************/
- void browser_gone(char *work_name, struct in_addr ip)
- {
- - struct subnet_record *d = find_domain(ip);
- + struct subnet_record *d = find_subnet(ip);
- struct work_record *work = find_workgroupstruct(d, work_name, False);
-
- + /* i don't know about this workgroup, therefore i don't care */
- if (!work || !d) return;
- -
- - if (strequal(work->work_group, lp_workgroup()) &&
- - d->my_interface)
- - {
- +
- + if (strequal(work->work_group, lp_workgroup()) && d->my_interface)
- + {
-
- DEBUG(2,("Forcing election on %s %s\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- /* we can attempt to become master browser */
- work->needelection = True;
- - }
- + }
- else
- - {
- - /* XXXX note: this will delete entries that have been added in by
- - lmhosts as well. a flag to ensure that these are not deleted may
- - be considered */
- -
- - /* workgroup with no master browser is not the default workgroup:
- - it's also not on our subnet. therefore delete it: it can be
- - recreated dynamically */
- -
- - send_election(d, work->work_group, 0, 0, myname);
- - remove_workgroup(d, work);
- - }
- + {
- + /* local interfaces: force an election */
- + if (d->my_interface)
- + send_election(d, work->work_group, 0, 0, myname);
- +
- + /* only removes workgroup completely on a local interface or
- + if there are no server entries on the remote interface.
- + (persistent lmhost entries on a remote interface will stop
- + the workgroup being removed. persistent lmhosts entries on
- + a local interface _will_ be removed).
- + */
- + remove_workgroup(d, work, d->my_interface);
- + }
- }
-
- +
- /****************************************************************************
- send an election packet
- **************************************************************************/
- @@ -137,7 +142,7 @@
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- - CVAL(p,0) = 8; /* election */
- + CVAL(p,0) = ANN_Election; /* election */
- p++;
-
- CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
- @@ -153,68 +158,318 @@
- }
-
-
- +/****************************************************************************
- + un-register a SELF name that got rejected.
- +
- + if this name happens to be rejected when samba is in the process
- + of becoming a master browser (registering __MSBROWSE__, WORKGROUP(1d)
- + or WORKGROUP(1b)) then we must stop being a master browser. sad.
- +
- + **************************************************************************/
- +void name_unregister_work(struct subnet_record *d, char *name, int name_type)
- +{
- + struct work_record *work;
- +
- + remove_netbios_name(d,name,name_type,SELF,ipzero);
- +
- + if (!(work = find_workgroupstruct(d, name, False))) return;
- +
- + if (ms_browser_name(name, name_type) ||
- + (AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
- + (name_type == 0x1d || name_type == 0x1b)))
- + {
- + int remove_type = 0;
- +
- + if (ms_browser_name(name, name_type))
- + remove_type = SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
- + if (name_type == 0x1d)
- + remove_type = SV_TYPE_MASTER_BROWSER;
- + if (name_type == 0x1b)
- + remove_type = SV_TYPE_DOMAIN_MASTER;
- +
- + become_nonmaster(d, work, remove_type);
- + }
- +}
- +
- +
- +/****************************************************************************
- + registers a name.
- +
- + if the name being added is a SELF name, we must additionally check
- + whether to proceed to the next stage in samba becoming a master browser.
- +
- + **************************************************************************/
- +void name_register_work(struct subnet_record *d, char *name, int name_type,
- + int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
- +{
- + enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
- + SELF : REGISTER;
- +
- + if (source == SELF)
- + {
- + struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
- +
- + add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
- +
- + if (work)
- + {
- + if (work->state != MST_NONE)
- + {
- + /* samba is in the process of working towards master browser-ness.
- + initiate the next stage.
- + */
- + become_master(d, work);
- + return;
- + }
- + }
- + }
- +}
- +
- +
- /*******************************************************************
- - become the master browser
- + become the master browser.
- +
- + this is done in stages. note that this could take a while,
- + particularly on a broadcast subnet, as we have to wait for
- + the implicit registration of each name to be accepted.
- +
- + as each name is successfully registered, become_master() is
- + called again, in order to initiate the next stage. see
- + dead_netbios_entry() - deals with implicit name registration
- + and response_name_reg() - deals with explicit registration
- + with a WINS server.
- +
- + stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
- + stage 2: was MST_WON - go to MST_MSB and register WORKGROUP(0x1d)
- + stage 3: was MST_MSB - go to MST_BROWSER and register WORKGROUP(0x1b)
- + stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
- +
- + XXXX note: this code still does not cope with the distinction
- + between different types of nodes, particularly between M and P
- + nodes. that comes later.
- +
- ******************************************************************/
- -static void become_master(struct subnet_record *d, struct work_record *work)
- +void become_master(struct subnet_record *d, struct work_record *work)
- {
- - uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
- + uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX|0x00400000;
-
- if (!work) return;
-
- - DEBUG(2,("Becoming master for %s\n",work->work_group));
- + DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
- + work->work_group,inet_ntoa(d->bcast_ip),work->state));
-
- - work->ServerType |= SV_TYPE_MASTER_BROWSER;
- - work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
- - work->ElectionCriterion |= 0x5;
- + switch (work->state)
- + {
- + case MST_NONE: /* while we were nothing but a server... */
- + {
- + DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
- + work->state = MST_WON; /* ... an election win was successful */
- +
- + work->ElectionCriterion |= 0x5;
- +
- + /* update our server status */
- + work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
- + add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
- +
- + /* add special browser name */
- + add_my_name_entry(d,MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
- +
- + /* DON'T do anything else after calling add_my_name_entry() */
- + return;
- + }
- + case MST_WON: /* while nothing had happened except we won an election... */
- + {
- + DEBUG(3,("go to second stage: register as master browser\n"));
- + work->state = MST_MSB; /* ... registering MSBROWSE was successful */
- +
- + /* add server entry on successful registration of MSBROWSE */
- + add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
- +
- + /* add master name */
- + add_my_name_entry(d,work->work_group,0x1d,NB_ACTIVE );
-
- - /* add browse, master and general names to database or register with WINS */
- - add_name_entry(MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
- - add_name_entry(work->work_group,0x1d,NB_ACTIVE );
- + /* DON'T do anything else after calling add_my_name_entry() */
- + return;
- + }
- + case MST_MSB: /* while we were still only registered MSBROWSE state... */
- + {
- + DEBUG(3,("2nd stage complete: registered as master browser\n"));
- + work->state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
- +
- + /* update our server status */
- + work->ServerType |= SV_TYPE_MASTER_BROWSER;
- + add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
- +
- + if (d->my_interface && work->serverlist == NULL) /* no servers! */
- + {
- + /* ask all servers on our local net to announce to us */
- + announce_request(work, d->bcast_ip);
- + }
- + break;
- + }
- +
- + case MST_BROWSER:
- + {
- + /* don't have to do anything: just report success */
- + DEBUG(3,("3rd stage: become master browser!\n"));
- +
- + break;
- + }
- +
- + case MST_DOMAIN_NONE:
- + {
- + if (lp_domain_master())
- + {
- + work->state = MST_DOMAIN_MEM; /* ... become domain member */
- + DEBUG(3,("domain first stage: register as domain member\n"));
- +
- + /* add domain member name */
- + add_my_name_entry(d,work->work_group,0x1e,NB_ACTIVE );
- +
- + /* DON'T do anything else after calling add_my_name_entry() */
- + return;
- + }
- + else
- + {
- + DEBUG(4,("samba not configured as a domain master.\n"));
- + }
- +
- + break;
- + }
- +
- + case MST_DOMAIN_MEM:
- + {
- + if (lp_domain_master())
- + {
- + work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
- + DEBUG(3,("domain second stage: register as domain master\n"));
- +
- + if (lp_domain_logons())
- + {
- + work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
- + add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
- + }
- +
- + /* add domain master name */
- + add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE );
- +
- + /* DON'T do anything else after calling add_my_name_entry() */
- + return;
- + }
- + else
- + {
- + DEBUG(4,("samba not configured as a domain master.\n"));
- + }
-
- - if (lp_domain_master())
- + break;
- + }
- +
- + case MST_DOMAIN_TST: /* while we were still a master browser... */
- {
- - DEBUG(4,("Domain master: adding names...\n"));
- -
- - /* add domain master and domain member names or register with WINS */
- - add_name_entry(work->work_group,0x1b,NB_ACTIVE);
- - work->ServerType |= SV_TYPE_DOMAIN_MASTER;
- + /* update our server status */
- + if (lp_domain_master())
- + {
- + struct subnet_record *d1;
- + uint32 update_type = 0;
- +
- + DEBUG(3,("domain third stage: samba is now a domain master.\n"));
- + work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
- +
- + update_type |= SV_TYPE_DOMAIN_MASTER;
-
- - if (lp_domain_logons())
- - {
- - work->ServerType |= SV_TYPE_DOMAIN_CTRL;
- - work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
- - }
- - }
- -
- - /* update our server status */
- - add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
- - add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
- + if (lp_domain_logons())
- + {
- + update_type |= SV_TYPE_DOMAIN_CTRL;
- + }
- +
- + work->ServerType |= update_type;
- + add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
- +
- + for (d1 = subnetlist; d1; d1 = d1->next)
- + {
- + struct work_record *w;
- + if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
- +
- + for (w = d1->workgrouplist; w; w = w->next)
- + {
- + struct server_record *s = find_server(w, myname);
- + if (strequal(w->work_group, work->work_group))
- + {
- + w->ServerType |= update_type;
- + }
- + if (s)
- + {
- + s->serv.type |= update_type;
- + DEBUG(4,("found server %s on %s: update to %8x\n",
- + s->serv.name, inet_ntoa(d1->bcast_ip),
- + s->serv.type));
- + }
- + }
- + }
- + }
-
- - if (d->my_interface)
- + break;
- + }
- +
- + case MST_DOMAIN:
- {
- - /* ask all servers on our local net to announce to us */
- - announce_request(work, d->bcast_ip);
- + /* don't have to do anything: just report success */
- + DEBUG(3,("fifth stage: there isn't one yet!\n"));
- + break;
- }
- + }
- }
-
-
- /*******************************************************************
- - unbecome the master browser
- + unbecome the master browser. initates removal of necessary netbios
- + names, and tells the world that we are no longer a master browser.
- ******************************************************************/
- -void become_nonmaster(struct subnet_record *d, struct work_record *work)
- +void become_nonmaster(struct subnet_record *d, struct work_record *work,
- + int remove_type)
- {
- + int new_server_type = work->ServerType;
- +
- DEBUG(2,("Becoming non-master for %s\n",work->work_group));
-
- - work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
- - work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
- - work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
- -
- - work->ElectionCriterion &= ~0x4;
- -
- - remove_name_entry(work->work_group,0x1b);
- - remove_name_entry(work->work_group,0x1d);
- - remove_name_entry(MSBROWSE ,0x01);
- + /* can only remove master or domain types with this function */
- + remove_type &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
- +
- + /* unbecome a master browser; unbecome a domain master, too :-( */
- + if (remove_type & SV_TYPE_MASTER_BROWSER)
- + remove_type |= SV_TYPE_DOMAIN_MASTER;
- +
- + new_server_type &= ~remove_type;
- +
- + if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
- + {
- + /* no longer a master browser of any sort */
- +
- + work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
- + work->ElectionCriterion &= ~0x4;
- + work->state = MST_NONE;
- +
- + /* announce ourselves as no longer active as a master browser. */
- + announce_server(d, work, work->work_group, myname, 0, 0);
- + remove_name_entry(d,MSBROWSE ,0x01);
- + }
- +
- + work->ServerType = new_server_type;
- +
- + if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
- + {
- + if (work->state == MST_DOMAIN)
- + work->state = MST_BROWSER;
- + remove_name_entry(d,work->work_group,0x1b);
- +
- + }
- +
- + if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
- + {
- + if (work->state >= MST_BROWSER)
- + work->state = MST_NONE;
- + remove_name_entry(d,work->work_group,0x1d);
- + }
- }
-
-
- @@ -234,27 +489,29 @@
- lastime = t;
-
- for (d = subnetlist; d; d = d->next)
- - {
- - struct work_record *work;
- - for (work = d->workgrouplist; work; work = work->next)
- + {
- + struct work_record *work;
- + for (work = d->workgrouplist; work; work = work->next)
- {
- if (work->RunningElection)
- - {
- - send_election(d,work->work_group, work->ElectionCriterion,
- + {
- + send_election(d,work->work_group, work->ElectionCriterion,
- t-StartupTime,myname);
-
- - if (work->ElectionCount++ >= 4)
- + if (work->ElectionCount++ >= 4)
- {
- /* I won! now what :-) */
- DEBUG(2,(">>> Won election on %s %s <<<\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- work->RunningElection = False;
- + work->state = MST_NONE;
- +
- become_master(d, work);
- }
- - }
- + }
- }
- - }
- + }
- }
-
-
- @@ -292,7 +549,7 @@
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d = find_domain(ip);
- + struct subnet_record *d = find_subnet(ip);
- int version = CVAL(buf,0);
- uint32 criterion = IVAL(buf,1);
- int timeup = IVAL(buf,5)/1000;
- @@ -320,6 +577,7 @@
- {
- work->needelection = True;
- work->ElectionCount=0;
- + work->state = MST_NONE;
- }
- }
- else
- @@ -334,9 +592,10 @@
-
- /* if we are the master then remove our masterly names */
- if (AM_MASTER(work))
- - {
- - become_nonmaster(d, work);
- - }
- + {
- + become_nonmaster(d, work,
- + SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
- + }
- }
- }
- }
- @@ -346,6 +605,11 @@
-
- /****************************************************************************
- checks whether a browser election is to be run on any workgroup
- +
- + this function really ought to return the time between election
- + packets (which depends on whether samba intends to be a domain
- + master or a master browser) in milliseconds.
- +
- ***************************************************************************/
- BOOL check_elections(void)
- {
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameelect.doc samba-1.9.16alpha11/source/nameelect.doc
- --- samba-1.9.16alpha10/source/nameelect.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameelect.doc Thu Jul 11 04:48:26 1996
- @@ -0,0 +1,214 @@
- +
- +the module nameelect.c deals with initiating, winning, losing
- +browsing elections, and checking if browsers are still around,
- +and the consequences of getting involved in all this.
- +
- +an election packet can be received at any time, which will initiate
- +an election. samba can also detect that there is no longer a
- +master browser and will initiate an election.
- +
- +there is one way to become a master browser, but there are two
- +ways to un-become a master browser. if you lose an election, you
- +must stop being a master browser. if you fail to register your
- +unique special browser names (either on your local subnet or with
- +the WINS server) then you must stop being a master browser.
- +
- +this is a double fail-safe mechanism to ensure that there is only
- +one master browser per workgroup per subnet (and one primary domain
- +controller - domain master browser - per domain (workgroup) per
- +wide area network).
- +
- +(a wide area network is created when one or more servers on a
- +broadcast-isolated subnet point to the same WINS server).
- +
- +
- +/*************************************************************************
- + check_elections()
- + *************************************************************************/
- +
- +this function returns True if samba is in the process of running an
- +election on any of its interfaces. a better version of this function
- +should return the time-out period in between election packets, in
- +milliseconds.
- +
- +
- +/*************************************************************************
- + process_election()
- + *************************************************************************/
- +
- +this function is responsible for dealing with the receipt of an election
- +browse MAILSLOT packet.
- +
- +if samba is running an election, it checks the criteria in the packet
- +received using win_election() to see if it has lost the election or if
- +it should join in the election.
- +
- +if it loses the election, then it becomes a non-master.
- +
- +
- +/*************************************************************************
- + win_election()
- + *************************************************************************/
- +
- +this function returns True if samba has won an election. the criteria
- +in order of precedence are:
- +
- +the election version; the election criteria; the time since samba was
- +started; and as a last resort, a name comparison is used.
- +
- +
- +/*************************************************************************
- + run_elections()
- + *************************************************************************/
- +
- +this function is responsible for sending out election packets if
- +samba is running in an election. once the fourth packet is sent
- +out, it is assumed that we have won, and samba initiates becoming
- +a master browser.
- +
- +(it looks like samba sends out an extra packet just to be sure...)
- +
- +
- +/*************************************************************************
- + become_nonmaster()
- + *************************************************************************/
- +
- +this function is responsible for down-grading samba's status from
- +either domain master to master browser or nothing, or master browser
- +to nothing, depending on its current status.
- +
- +samba can become a non-master in three ways: by losing an election -
- +see process_election(); by having one of its special browser names
- +de-registered - see name_unregister_work(); by receiving and
- +processing a browser reset packet - see process_reset_browser().
- +
- +when samba stops being a domain master, it must release its unique
- +0x1b name. when samba stops being a master browser, it must release
- +its unique 0x1d name.
- +
- +becoming non-master is done on a per-subnet basis.
- +
- +
- +/*************************************************************************
- + become_master()
- + *************************************************************************/
- +
- +this function is responsible for slowly turning samba into a
- +master browser or a domain master (primary domain controller).
- +
- +
- +this is done in stages. note that this could take a while,
- +particularly on a broadcast subnet, as we have to wait for
- +the implicit registration of each name to be accepted.
- +
- +as each name is successfully registered, become_master() is
- +called again via name_register_work(), in order to initiate
- +the next stage (see dead_netbios_entry() - deals with implicit
- +name registration and response_name_reg() - deals with explicit
- +registration with a WINS server).
- +
- +stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
- +stage 2: was MST_WON - go to MST_MSB and register WORKGROUP(0x1d)
- +stage 3: was MST_MSB - go to MST_BROWSER and register WORKGROUP(0x1b)
- +stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
- +
- +note that this code still does not cope with the distinction
- +between different types of nodes, particularly between M and P
- +nodes (see rfc1001.txt). that will be developed later.
- +
- +
- +/*************************************************************************
- + name_register_work()
- + *************************************************************************/
- +
- +this function is called when a NetBIOS name is successfully
- +registered. it will add the registered name into samba's NetBIOS
- +records.
- +
- +it has the additional responsibility that when samba is becoming
- +a master browser, it must initiate the next stage in the progress
- +towards becoming a master browser.
- +
- +implicit name registration is done through dead_netbios_entry()
- +by time-out. explicit name registration is done through
- +response_name_reg() with a WINS server.
- +
- +
- +/*************************************************************************
- + name_unregister_work()
- + *************************************************************************/
- +
- +this function is called when there is an objection to a NetBIOS
- +name being registered. this will always be done through a negative
- +response to a name registration, whether it be by a host that
- +already owns the unique name being registered on a subnet, or
- +by a WINS server.
- +
- +the name being objected to must be removed from samba's records.
- +
- +it has the additional responsibility of checking whether samba is
- +currently a master browser or not, and if so it should initiate
- +becoming a non-master.
- +
- +
- +
- +/*************************************************************************
- + send_election()
- + *************************************************************************/
- +
- +this function is responsible for sending a browse mailslot
- +datagram election packet (of type ANN_Election). it constructs
- +the packet with all the relevant info needed to participate:
- +election version; election criteria; time since startup and
- +our name.
- +
- +this function can be used to ensure that initiate but lose an
- +election by specifying a criteria and time up of zero. this
- +is necessary if we are a master browser and we are about to
- +go down (politely!) - see nmbd.c:sig_term().
- +
- +
- +/*************************************************************************
- + browser_gone()
- + *************************************************************************/
- +
- +this function is responsible for dealing with the instance when
- +the master browser we thought was present on a subnet is no longer
- +responding.
- +
- +if it is samba's workgroup, and it's a local interface, samba
- +detects that it can participate in an election on that interface
- +and potentially become a master browser or domain master.
- +
- +if it's a local subnet and not one of samba's workgroups, then
- +samba will force an election (which it is not obliged to do).
- +remove_workgroup() will be expected to remove all references
- +to this workgroup and the servers in it from the database.
- +
- +if it's a remote subnet and not one of samba's workgroups then
- +no election is forced, and remove_workgroup() will be expected
- +to remove all server entries from this workgroup _except_ those
- +added from the lmhosts file. if there are entries added from
- +the lmhosts file, then the workgroup entry will remain,
- +otherwise it too will be removed.
- +
- +
- +/*************************************************************************
- + check_master_browser()
- + *************************************************************************/
- +
- +this function is responsible for periodically checking whether
- +master browsers that samba expects to be alive are alive. this
- +is done every CHECK_TIME_MST_BROWSE minutes.
- +
- +for every workgroup record for which samba is not a master browser,
- +on both local and remote interfaces, samba will initiate a
- +broadcast query for a master browser on that subnet.
- +
- +(browser_gone() will be called to deal with the case where no
- +response is received to the NAME_QUERY_MST_CHK initiated here.
- +no action is required when a response _is_ received, however:
- +see nameservresp.c:response_process() and dead_netbios_entry()
- +for details)
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namelogon.c samba-1.9.16alpha11/source/namelogon.c
- --- samba-1.9.16alpha10/source/namelogon.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namelogon.c Wed Jul 3 01:31:12 1996
- @@ -0,0 +1,119 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- +*/
- +
- +#include "includes.h"
- +
- +extern int ClientDGRAM;
- +
- +#define TEST_CODE /* want to debug unknown browse packets */
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring myname;
- +
- +
- +/****************************************************************************
- + process a domain logon packet
- + **************************************************************************/
- +void process_logon_packet(struct packet_struct *p,char *buf,int len)
- +{
- + struct dgram_packet *dgram = &p->packet.dgram;
- + struct in_addr ip = dgram->header.source_ip;
- + struct subnet_record *d = find_subnet(ip);
- + char *logname,*q;
- + char *reply_name;
- + BOOL add_slashes = False;
- + pstring outbuf;
- + int code,reply_code;
- + struct work_record *work;
- +
- + if (!d) return;
- +
- + if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
- + return;
- +
- + if (!lp_domain_logons()) {
- + DEBUG(3,("No domain logons\n"));
- + return;
- + }
- + if (!listening_name(work, &dgram->dest_name))
- + {
- + DEBUG(4,("Not listening to that domain\n"));
- + return;
- + }
- +
- + code = SVAL(buf,0);
- + switch (code) {
- + case 0:
- + {
- + char *machine = buf+2;
- + char *user = skip_string(machine,1);
- + logname = skip_string(user,1);
- + reply_code = 6;
- + reply_name = myname;
- + add_slashes = True;
- + DEBUG(3,("Domain login request from %s(%s) user=%s\n",
- + machine,inet_ntoa(p->ip),user));
- + }
- + break;
- + case 7:
- + {
- + char *machine = buf+2;
- + logname = skip_string(machine,1);
- + reply_code = 7;
- + reply_name = lp_domain_controller();
- + if (!*reply_name) {
- + DEBUG(3,("No domain controller configured\n"));
- + return;
- + }
- + DEBUG(3,("GETDC request from %s(%s)\n",
- + machine,inet_ntoa(p->ip)));
- + }
- + break;
- + default:
- + DEBUG(3,("Unknown domain request %d\n",code));
- + return;
- + }
- +
- + bzero(outbuf,sizeof(outbuf));
- + q = outbuf;
- + SSVAL(q,0,reply_code);
- + q += 2;
- + if (add_slashes) {
- + strcpy(q,"\\\\");
- + q += 2;
- + }
- + StrnCpy(q,reply_name,16);
- + strupper(q);
- + q = skip_string(q,1);
- + SSVAL(q,0,0xFFFF);
- + q += 2;
- +
- + send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
- + myname,&dgram->source_name.name[0],0x20,0,p->ip,
- + *iface_ip(p->ip));
- +}
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namelogon.doc samba-1.9.16alpha11/source/namelogon.doc
- --- samba-1.9.16alpha10/source/namelogon.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namelogon.doc Sun Jul 7 22:35:55 1996
- @@ -0,0 +1,9 @@
- +this module deals with the first stage of domain logons. there is much
- +more work to be done on this: it's all totally undocumented.
- +
- +
- +/*************************************************************************
- + process_logon_packet()
- + *************************************************************************/
- +
- +a function that processes logon packets (the most helpful comment yet :-).
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namepacket.c samba-1.9.16alpha11/source/namepacket.c
- --- samba-1.9.16alpha10/source/namepacket.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namepacket.c Thu Jul 18 20:53:15 1996
- @@ -0,0 +1,581 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- +*/
- +
- +#include "includes.h"
- +
- +extern int ClientNMB;
- +extern int ClientDGRAM;
- +
- +extern int DEBUGLEVEL;
- +
- +extern int num_response_packets;
- +
- +BOOL CanRecurse = True;
- +extern pstring scope;
- +extern struct in_addr ipgrp;
- +
- +static uint16 name_trn_id=0;
- +
- +
- +/***************************************************************************
- + updates the unique transaction identifier
- + **************************************************************************/
- +void debug_browse_data(char *outbuf, int len)
- +{
- + int i,j;
- + for (i = 0; i < len; i+= 16)
- + {
- + DEBUG(4, ("%3x char ", i));
- +
- + for (j = 0; j < 16; j++)
- + {
- + unsigned char x = outbuf[i+j];
- + if (x < 32 || x > 127) x = '.';
- +
- + if (i+j >= len) break;
- + DEBUG(4, ("%c", x));
- + }
- +
- + DEBUG(4, (" hex ", i));
- +
- + for (j = 0; j < 16; j++)
- + {
- + if (i+j >= len) break;
- + DEBUG(4, (" %02x", outbuf[i+j]));
- + }
- +
- + DEBUG(4, ("\n"));
- + }
- +
- +}
- +
- +
- +/***************************************************************************
- + updates the unique transaction identifier
- + **************************************************************************/
- +static void update_name_trn_id(void)
- +{
- + if (!name_trn_id)
- + {
- + name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
- + }
- + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- +}
- +
- +
- +/****************************************************************************
- + initiate a netbios packet
- + ****************************************************************************/
- +void initiate_netbios_packet(uint16 *id,
- + int fd,int quest_type,char *name,int name_type,
- + int nb_flags,BOOL bcast,BOOL recurse,
- + struct in_addr to_ip)
- +{
- + struct packet_struct p;
- + struct nmb_packet *nmb = &p.packet.nmb;
- + struct res_rec additional_rec;
- + char *packet_type = "unknown";
- + int opcode = -1;
- +
- + if (!id) return;
- +
- + if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
- + if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
- + if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
- + if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
- +
- + DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
- + packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
- +
- + if (opcode == -1) return;
- +
- + bzero((char *)&p,sizeof(p));
- +
- + if (*id == 0xffff) {
- + update_name_trn_id();
- + *id = name_trn_id; /* allow resending with same id */
- + }
- +
- + nmb->header.name_trn_id = *id;
- + nmb->header.opcode = opcode;
- + nmb->header.response = False;
- +
- + nmb->header.nm_flags.bcast = bcast;
- + nmb->header.nm_flags.recursion_available = CanRecurse;
- + nmb->header.nm_flags.recursion_desired = recurse;
- + nmb->header.nm_flags.trunc = False;
- + nmb->header.nm_flags.authoritative = False;
- +
- + nmb->header.rcode = 0;
- + nmb->header.qdcount = 1;
- + nmb->header.ancount = 0;
- + nmb->header.nscount = 0;
- + nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
- +
- + make_nmb_name(&nmb->question.question_name,name,name_type,scope);
- +
- + nmb->question.question_type = quest_type;
- + nmb->question.question_class = 0x1;
- +
- + if (quest_type == NMB_REG || quest_type == NMB_REL)
- + {
- + nmb->additional = &additional_rec;
- + bzero((char *)nmb->additional,sizeof(*nmb->additional));
- +
- + nmb->additional->rr_name = nmb->question.question_name;
- + nmb->additional->rr_type = nmb->question.question_type;
- + nmb->additional->rr_class = nmb->question.question_class;
- +
- + nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
- + nmb->additional->rdlength = 6;
- + nmb->additional->rdata[0] = nb_flags;
- + putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
- + }
- +
- + p.ip = to_ip;
- + p.port = NMB_PORT;
- + p.fd = fd;
- + p.timestamp = time(NULL);
- + p.packet_type = NMB_PACKET;
- +
- + if (!send_packet(&p)) *id = 0xffff;
- +
- + return;
- +}
- +
- +
- +/****************************************************************************
- + reply to a netbios name packet
- + ****************************************************************************/
- +void reply_netbios_packet(struct packet_struct *p1,int trn_id,
- + int rcode, int rcv_code, int opcode, BOOL recurse,
- + struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
- + char *data,int len)
- +{
- + struct packet_struct p;
- + struct nmb_packet *nmb = &p.packet.nmb;
- + struct res_rec answers;
- + char *packet_type = "unknown";
- + BOOL recursion_desired = False;
- +
- + p = *p1;
- +
- + switch (rcv_code)
- + {
- + case NMB_STATUS:
- + {
- + packet_type = "nmb_status";
- + recursion_desired = True;
- + break;
- + }
- + case NMB_QUERY:
- + {
- + packet_type = "nmb_query";
- + recursion_desired = True;
- + break;
- + }
- + case NMB_REG:
- + {
- + packet_type = "nmb_reg";
- + recursion_desired = True;
- + break;
- + }
- + case NMB_REL:
- + {
- + packet_type = "nmb_rel";
- + recursion_desired = False;
- + break;
- + }
- + case NMB_WAIT_ACK:
- + {
- + packet_type = "nmb_wack";
- + recursion_desired = False;
- + break;
- + }
- + default:
- + {
- + DEBUG(1,("replying netbios packet: %s %s\n",
- + packet_type, namestr(rr_name), inet_ntoa(p.ip)));
- +
- + return;
- + }
- + }
- +
- + DEBUG(4,("replying netbios packet: %s %s\n",
- + packet_type, namestr(rr_name), inet_ntoa(p.ip)));
- +
- + nmb->header.name_trn_id = trn_id;
- + nmb->header.opcode = opcode;
- + nmb->header.response = True;
- + nmb->header.nm_flags.bcast = False;
- + nmb->header.nm_flags.recursion_available = recurse;
- + nmb->header.nm_flags.recursion_desired = recursion_desired;
- + nmb->header.nm_flags.trunc = False;
- + nmb->header.nm_flags.authoritative = True;
- +
- + nmb->header.qdcount = 0;
- + nmb->header.ancount = 1;
- + nmb->header.nscount = 0;
- + nmb->header.arcount = 0;
- + nmb->header.rcode = 0;
- +
- + bzero((char*)&nmb->question,sizeof(nmb->question));
- +
- + nmb->answers = &answers;
- + bzero((char*)nmb->answers,sizeof(*nmb->answers));
- +
- + nmb->answers->rr_name = *rr_name;
- + nmb->answers->rr_type = rr_type;
- + nmb->answers->rr_class = rr_class;
- + nmb->answers->ttl = ttl;
- +
- + if (data && len)
- + {
- + nmb->answers->rdlength = len;
- + memcpy(nmb->answers->rdata, data, len);
- + }
- +
- + p.packet_type = NMB_PACKET;
- +
- + debug_nmb_packet(&p);
- +
- + send_packet(&p);
- +}
- +
- +
- +/*******************************************************************
- + the global packet linked-list. incoming entries are added to the
- + end of this list. it is supposed to remain fairly short so we
- + won't bother with an end pointer.
- + ******************************************************************/
- +static struct packet_struct *packet_queue = NULL;
- +
- +/*******************************************************************
- + queue a packet into the packet queue
- + ******************************************************************/
- +void queue_packet(struct packet_struct *packet)
- +{
- + struct packet_struct *p;
- +
- + if (!packet_queue) {
- + packet->prev = NULL;
- + packet->next = NULL;
- + packet_queue = packet;
- + return;
- + }
- +
- + /* find the bottom */
- + for (p=packet_queue;p->next;p=p->next) ;
- +
- + p->next = packet;
- + packet->next = NULL;
- + packet->prev = p;
- +}
- +
- +
- +/****************************************************************************
- + process udp 138 datagrams
- + ****************************************************************************/
- +static void process_dgram(struct packet_struct *p)
- +{
- + char *buf;
- + char *buf2;
- + int len;
- + struct dgram_packet *dgram = &p->packet.dgram;
- +
- + if (dgram->header.msg_type != 0x10 &&
- + dgram->header.msg_type != 0x11 &&
- + dgram->header.msg_type != 0x12) {
- + /* don't process error packets etc yet */
- + return;
- + }
- +
- + buf = &dgram->data[0];
- + buf -= 4; /* XXXX for the pseudo tcp length -
- + someday I need to get rid of this */
- +
- + if (CVAL(buf,smb_com) != SMBtrans) return;
- +
- + len = SVAL(buf,smb_vwv11);
- + buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
- +
- + DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
- + namestr(&dgram->source_name),namestr(&dgram->dest_name),
- + smb_buf(buf),CVAL(buf2,0),len));
- +
- +
- + if (len <= 0) return;
- +
- + /* datagram packet received for the browser mailslot */
- + if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
- + process_browse_packet(p,buf2,len);
- + return;
- + }
- +
- + /* datagram packet received for the domain log on mailslot */
- + if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
- + process_logon_packet(p,buf2,len);
- + return;
- + }
- +}
- +
- +/****************************************************************************
- + process a nmb packet
- + ****************************************************************************/
- +static void process_nmb(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- +
- + debug_nmb_packet(p);
- +
- + switch (nmb->header.opcode)
- + {
- + case 8: /* what is this?? */
- + case NMB_REG:
- + case NMB_REG_REFRESH:
- + {
- + if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
- + if (nmb->header.response)
- + response_netbios_packet(p); /* response to registration dealt with here */
- + else
- + reply_name_reg(p);
- + break;
- + }
- +
- + case 0:
- + {
- + if (nmb->header.response)
- + {
- + switch (nmb->question.question_type)
- + {
- + case 0x0:
- + {
- + response_netbios_packet(p);
- + break;
- + }
- + }
- + return;
- + }
- + else if (nmb->header.qdcount>0)
- + {
- + switch (nmb->question.question_type)
- + {
- + case NMB_QUERY:
- + {
- + reply_name_query(p);
- + break;
- + }
- + case NMB_STATUS:
- + {
- + reply_name_status(p);
- + break;
- + }
- + }
- + return;
- + }
- + break;
- + }
- +
- + case NMB_REL:
- + {
- + if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- + {
- + DEBUG(2,("netbios release packet rejected\n"));
- + break;
- + }
- +
- + if (nmb->header.response)
- + response_netbios_packet(p); /* response to reply dealt with in here */
- + else
- + reply_name_release(p);
- + break;
- + }
- + }
- +}
- +
- +
- +/*******************************************************************
- + run elements off the packet queue till its empty
- + ******************************************************************/
- +void run_packet_queue()
- +{
- + struct packet_struct *p;
- +
- + while ((p=packet_queue))
- + {
- + switch (p->packet_type)
- + {
- + case NMB_PACKET:
- + process_nmb(p);
- + break;
- +
- + case DGRAM_PACKET:
- + process_dgram(p);
- + break;
- + }
- +
- + packet_queue = packet_queue->next;
- + if (packet_queue) packet_queue->prev = NULL;
- + free_packet(p);
- + }
- +}
- +
- +/****************************************************************************
- + listens for NMB or DGRAM packets, and queues them
- + ***************************************************************************/
- +void listen_for_packets(BOOL run_election)
- +{
- + fd_set fds;
- + int selrtn;
- + struct timeval timeout;
- +
- + FD_ZERO(&fds);
- + FD_SET(ClientNMB,&fds);
- + FD_SET(ClientDGRAM,&fds);
- +
- + /* during elections and when expecting a netbios response packet we need
- + to send election packets at one second intervals.
- + XXXX actually, it needs to be the interval (in ms) between time now and the
- + time we are expecting the next netbios packet */
- +
- + timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
- + timeout.tv_usec = 0;
- +
- + selrtn = sys_select(&fds,&timeout);
- +
- + if (FD_ISSET(ClientNMB,&fds))
- + {
- + struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
- + if (packet) {
- +#if 1
- + if (ismyip(packet->ip) &&
- + (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- + DEBUG(5,("discarding own packet from %s:%d\n",
- + inet_ntoa(packet->ip),packet->port));
- + free_packet(packet);
- + } else
- +#endif
- + {
- + queue_packet(packet);
- + }
- + }
- + }
- +
- + if (FD_ISSET(ClientDGRAM,&fds))
- + {
- + struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
- + if (packet) {
- +#if 1
- + if (ismyip(packet->ip) &&
- + (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- + DEBUG(5,("discarding own packet from %s:%d\n",
- + inet_ntoa(packet->ip),packet->port));
- + free_packet(packet);
- + } else
- +#endif
- + {
- + queue_packet(packet);
- + }
- + }
- + }
- +}
- +
- +
- +
- +/****************************************************************************
- + construct and send a netbios DGRAM
- +
- + Note that this currently sends all answers to port 138. thats the
- + wrong things to do! I should send to the requestors port. XXX
- + **************************************************************************/
- +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
- + char *dstname,int src_type,int dest_type,
- + struct in_addr dest_ip,struct in_addr src_ip)
- +{
- + struct packet_struct p;
- + struct dgram_packet *dgram = &p.packet.dgram;
- + struct in_addr wins_ip = ipgrp;
- + char *ptr,*p2;
- + char tmp[4];
- +
- + /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
- + if (ip_equal(wins_ip, dest_ip)) return False;
- +
- + bzero((char *)&p,sizeof(p));
- +
- + update_name_trn_id();
- +
- + dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
- + dgram->header.flags.node_type = M_NODE;
- + dgram->header.flags.first = True;
- + dgram->header.flags.more = False;
- + dgram->header.dgm_id = name_trn_id;
- + dgram->header.source_ip = src_ip;
- + dgram->header.source_port = DGRAM_PORT;
- + dgram->header.dgm_length = 0; /* let build_dgram() handle this */
- + dgram->header.packet_offset = 0;
- +
- + make_nmb_name(&dgram->source_name,srcname,src_type,scope);
- + make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
- +
- + ptr = &dgram->data[0];
- +
- + /* now setup the smb part */
- + ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
- + memcpy(tmp,ptr,4);
- + set_message(ptr,17,17 + len,True);
- + memcpy(ptr,tmp,4);
- +
- + CVAL(ptr,smb_com) = SMBtrans;
- + SSVAL(ptr,smb_vwv1,len);
- + SSVAL(ptr,smb_vwv11,len);
- + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- + SSVAL(ptr,smb_vwv13,3);
- + SSVAL(ptr,smb_vwv14,1);
- + SSVAL(ptr,smb_vwv15,1);
- + SSVAL(ptr,smb_vwv16,2);
- + p2 = smb_buf(ptr);
- + strcpy(p2,mailslot);
- + p2 = skip_string(p2,1);
- +
- + memcpy(p2,buf,len);
- + p2 += len;
- +
- + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
- +
- + p.ip = dest_ip;
- + p.port = DGRAM_PORT;
- + p.fd = ClientDGRAM;
- + p.timestamp = time(NULL);
- + p.packet_type = DGRAM_PACKET;
- +
- + DEBUG(4,("send mailslot %s from %s %s", mailslot,
- + inet_ntoa(src_ip),namestr(&dgram->source_name)));
- + DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
- +
- + return(send_packet(&p));
- +}
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namepacket.doc samba-1.9.16alpha11/source/namepacket.doc
- --- samba-1.9.16alpha10/source/namepacket.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namepacket.doc Sun Jul 7 22:35:55 1996
- @@ -0,0 +1,106 @@
- +this module deals with packets: sending, receiving, queueing
- +and some basic interpretation (e.g it excludes datagram
- +error packets at the moment).
- +
- +the packet queueing mechanism was originally introduced when
- +samba dealt with responses by sending a packet, receiving
- +packets and queueing all packets that didn't match up with
- +the response expected. this is fine in a single-thread
- +environment, but samba now deals with response packets by
- +queueing the responses. to some extent, therefore, this
- +queue_packet mechanism is redundant.
- +
- +
- +/*************************************************************************
- + send_mailslot_reply()
- + *************************************************************************/
- +
- +this function is responsible for sending a MAILSLOT packet.
- +
- +it will _not_ send packets to the pseudo WINS subnet's address of
- +255.255.255.255: this would be disastrous.
- +
- +each packet sent out has a unique transaction identifier. this is done
- +so that responses can be matched later with the original purpose for
- +the packet being sent out in the first place.
- +
- +
- +/*************************************************************************
- + listen_for_packets()
- + *************************************************************************/
- +
- +this function is responsible for reading NMB and DGRAM packets, and then
- +queueing them. it will normally time-out for NMBD_SELECT_LOOP seconds, but
- +if there is an election currently running or we are expecting a response
- +then this time is reduced to 1 second.
- +
- +note: the time-out period needs refining to the millisecond level.
- +
- +
- +/*************************************************************************
- + queue_packet()
- + *************************************************************************/
- +
- +this function is responsible for queueing any NMB and DGRAM packets passed
- +to it. these packets will be removed from the queue in run_packet_queue().
- +
- +
- +/*************************************************************************
- + run_packet_queue()
- + *************************************************************************/
- +
- +this function is responsible for taking a packet off the queue,
- +identifying whether it is an NMB or a DGRAM packet, processing
- +it accordingly and deleting it. this process continues until
- +there are no more packets on the queue.
- +
- +
- +/*************************************************************************
- + process_nmb()
- + *************************************************************************/
- +
- +this function receives a packet identified as a netbios packet.
- +it further identifies whether it is a response or a query packet.
- +by identifying the type of packet (name registration, query etc)
- +process_nmb() will call the appropriate function to deal with the
- +type of packet received.
- +
- +
- +/*************************************************************************
- + process_dgram()
- + *************************************************************************/
- +
- +this function is responsible for identifying whether the datagram
- +packet received is a browser packet or a domain logon packet. it
- +also does some filtering of certain types of packets (e.g it
- +filters out error packets).
- +
- +
- +/*************************************************************************
- + reply_netbios_packet()
- + *************************************************************************/
- +
- +this function is responsible for sending a reply to another NetBIOS
- +packet from another host. it can be used to send a reply to a name
- +registration, name release, name query or name status request.
- +
- +the reply can be either a positive or a negative one.
- +
- +
- +/*************************************************************************
- + initiate_netbios_packet()
- + *************************************************************************/
- +
- +this function is responsible for construction a netbios packet and sending
- +it. if the packet has not had a unique transaction id allocated to it,
- +then initiate_netbios_packet() will give it one.
- +
- +
- +/*************************************************************************
- + update_name_trn_id()
- + *************************************************************************/
- +
- +this function is responsible for allocating unique transaction identifiers
- +for each new packet sent on the network.
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namequery.c samba-1.9.16alpha11/source/namequery.c
- --- samba-1.9.16alpha10/source/namequery.c Tue Jun 4 16:41:15 1996
- +++ samba-1.9.16alpha11/source/namequery.c Thu Jul 18 20:53:15 1996
- @@ -173,6 +173,8 @@
- continue;
- }
-
- + debug_nmb_packet(p2);
- +
- _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
- free_packet(p2);
- return(True);
- @@ -266,6 +268,8 @@
- continue;
- }
-
- + debug_nmb_packet(p2);
- +
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namequery.doc samba-1.9.16alpha11/source/namequery.doc
- --- samba-1.9.16alpha10/source/namequery.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namequery.doc Sun Jul 7 22:35:56 1996
- @@ -0,0 +1,56 @@
- +this module contains non-threaded versions of name status and name
- +query functions. if a multi-threaded nmbd was to be written, these
- +functions would be the starting point.
- +
- +at the moment, the expected response queueing system is used to
- +replace these functions without needing to multi-thread nmbd.
- +
- +these functions are used in smbclient and nmblookup at present to
- +avoid having the vast quantities of complex and unused code needed
- +to support even a simple name query (or providing stubs for the
- +unused side of these functions).
- +
- +there is a down-side to these functions, which is all microsoft's
- +fault. microsoft machines always always reply to queries on the
- +priveleged ports, rather than following the usual tcp/ip mechanism
- +of replying on the client's port (the exception to this i am led
- +to believe is windows nt 3.50).
- +
- +as a result of this, in order to receive a response to a name
- +query from a microsoft machine, we must be able to listen on
- +the priveleged netbios name server ports. this is simply not
- +possible with some versions of unix, unless you have root access.
- +
- +it is also not possible if you run smbclient or nmblookup on an
- +interface that already has been claimed by the netbios name server
- +daemon nmbd.
- +
- +all in all, i wish that microsoft would fix this.
- +
- +a solution does exist: nmbd _does_ actually reply on the client's
- +port, so if smbclient and nmblookup were to use nmbd as a proxy
- +forwarder of queries (or to use samba's WINS capabilities) then
- +a query could be made without needing access to the priveleged
- +ports. in order to do this properly, samba must implement secured
- +netbios name server functionality (see rfc1001.txt 15.1.6).
- +
- +
- +/*************************************************************************
- + name_query()
- + *************************************************************************/
- +
- +
- +
- +/*************************************************************************
- + name_status()
- + *************************************************************************/
- +
- +
- +
- +/*************************************************************************
- + _interpret_node_status()
- + *************************************************************************/
- +
- +
- +this is a older version of interpret_node_status().
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameresp.c samba-1.9.16alpha11/source/nameresp.c
- --- samba-1.9.16alpha10/source/nameresp.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/nameresp.c Thu Jul 18 20:53:15 1996
- @@ -2,7 +2,7 @@
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios library routines
- - Copyright (C) Andrew Tridgell 1994-1995
- + Copyright (C) Andrew Tridgell 1994-1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- @@ -18,6 +18,8 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- + Module name: nameresp.c
- +
- */
-
- #include "includes.h"
- @@ -25,214 +27,192 @@
- extern int ClientNMB;
- extern int ClientDGRAM;
-
- -/* this is our initiated name query response database */
- -struct name_response_record *nameresponselist = NULL;
- +extern struct subnet_record *subnetlist;
-
- extern int DEBUGLEVEL;
-
- -static uint16 name_trn_id=0;
- -BOOL CanRecurse = True;
- extern pstring scope;
- -extern pstring myname;
- extern struct in_addr ipzero;
- +extern struct in_addr ipgrp;
-
-
- /***************************************************************************
- - add an initated name query into the list
- + deals with an entry before it dies
- **************************************************************************/
- -extern void add_response_record(struct name_response_record *n)
- +static void dead_netbios_entry(struct subnet_record *d,
- + struct response_record *n)
- {
- - struct name_response_record *n2;
- + DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
- + inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
-
- - if (!nameresponselist)
- - {
- - nameresponselist = n;
- - n->prev = NULL;
- - n->next = NULL;
- - return;
- + debug_state_type(n->state);
- +
- + switch (n->state)
- + {
- + case NAME_QUERY_CONFIRM:
- + {
- + if (!lp_wins_support()) return; /* only if we're a WINS server */
- +
- + if (n->num_msgs == 0)
- + {
- + /* oops. name query had no response. check that the name is
- + unique and then remove it from our WINS database */
- +
- + /* IMPORTANT: see query_refresh_names() */
- +
- + if ((!NAME_GROUP(n->nb_flags)))
- + {
- + struct subnet_record *d1 = find_subnet(ipgrp);
- + if (d1)
- + {
- + /* remove the name that had been registered with us,
- + and we're now getting no response when challenging.
- + see rfc1001.txt 15.5.2
- + */
- + remove_netbios_name(d1, n->name.name, n->name.name_type,
- + REGISTER, n->send_ip);
- + }
- + }
- + }
- + break;
- }
- -
- - for (n2 = nameresponselist; n2->next; n2 = n2->next) ;
- -
- - n2->next = n;
- - n->next = NULL;
- - n->prev = n2;
- -}
-
- + case NAME_QUERY_MST_CHK:
- + {
- + /* if no response received, the master browser must have gone
- + down on that subnet, without telling anyone. */
-
- -/*******************************************************************
- - remove old name response entries
- - ******************************************************************/
- -void expire_netbios_response_entries(time_t t)
- -{
- - struct name_response_record *n;
- - struct name_response_record *nextn;
- + /* IMPORTANT: see response_netbios_packet() */
-
- - for (n = nameresponselist; n; n = nextn)
- - {
- - if (n->start_time < t)
- + if (n->num_msgs == 0)
- + browser_gone(n->name.name, n->send_ip);
- + break;
- + }
- +
- + case NAME_RELEASE:
- {
- - DEBUG(3,("Removing dead name query for %s %s (num_msgs=%d)\n",
- - inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
- + /* if no response received, it must be OK for us to release the
- + name. nobody objected (including a potentially dead or deaf
- + WINS server) */
-
- - if (n->cmd_type == CHECK_MASTER)
- - {
- - /* if no response received, the master browser must have gone */
- - if (n->num_msgs == 0)
- - browser_gone(n->name.name, n->to_ip);
- - }
- -
- - nextn = n->next;
- -
- - if (n->prev) n->prev->next = n->next;
- - if (n->next) n->next->prev = n->prev;
- -
- - if (nameresponselist == n) nameresponselist = n->next;
- -
- - free(n);
- + /* IMPORTANT: see response_name_release() */
- +
- + if (ismyip(n->send_ip))
- + {
- + name_unregister_work(d,n->name.name,n->name.name_type);
- + }
- + if (!n->bcast)
- + {
- + DEBUG(0,("WINS server did not respond to name release!\n"));
- + /* XXXX whoops. we have problems. must deal with this */
- + }
- + break;
- }
- - else
- +
- + case NAME_REGISTER_CHALLENGE:
- {
- - nextn = n->next;
- + /* name challenge: no reply. we can reply to the person that
- + wanted the unique name and tell them that they can have it
- + */
- +
- + add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
- + n->nb_flags, GET_TTL(0),
- + n->reply_to_ip, False, n->reply_to_ip);
- +
- + if (!n->bcast)
- + {
- + DEBUG(1,("WINS server did not respond to name registration!\n"));
- + /* XXXX whoops. we have problems. must deal with this */
- + }
- + break;
- }
- - }
- -}
-
- + case NAME_REGISTER:
- + {
- + /* if no response received, and we are using a broadcast registration
- + method, it must be OK for us to register the name: nobody objected
- + on that subnet. if we are using a WINS server, then the WINS
- + server must be dead or deaf.
- + */
- + if (n->bcast)
- + {
- + /* broadcast method: implicit acceptance of the name registration
- + by not receiving any objections. */
-
- -/****************************************************************************
- - reply to a netbios name packet
- - ****************************************************************************/
- -void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,
- - int opcode,BOOL recurse,struct nmb_name *rr_name,
- - int rr_type,int rr_class,int ttl,char *data,int len)
- -{
- - struct packet_struct p;
- - struct nmb_packet *nmb = &p.packet.nmb;
- - struct res_rec answers;
- - char *packet_type = "unknown";
- -
- - p = *p1;
- + /* IMPORTANT: see response_name_reg() */
-
- - if (rr_type == NMB_STATUS) packet_type = "nmb_status";
- - if (rr_type == NMB_QUERY ) packet_type = "nmb_query";
- - if (rr_type == NMB_REG ) packet_type = "nmb_reg";
- - if (rr_type == NMB_REL ) packet_type = "nmb_rel";
- -
- - DEBUG(4,("replying netbios packet: %s %s\n",
- - packet_type, namestr(rr_name), inet_ntoa(p.ip)));
- + name_register_work(d,n->name.name,n->name.name_type,
- + n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
- + }
- + else
- + {
- + /* received no response. rfc1001.txt states that after retrying,
- + we should assume the WINS server is dead, and fall back to
- + broadcasting (see bits about M nodes: can't find any right
- + now) */
- +
- + DEBUG(1,("WINS server did not respond to name registration!\n"));
- + /* XXXX whoops. we have problems. must deal with this */
- + }
- + break;
- + }
-
- - nmb->header.name_trn_id = trn_id;
- - nmb->header.opcode = opcode;
- - nmb->header.response = True;
- - nmb->header.nm_flags.bcast = False;
- - nmb->header.nm_flags.recursion_available = recurse;
- - nmb->header.nm_flags.recursion_desired = True;
- - nmb->header.nm_flags.trunc = False;
- - nmb->header.nm_flags.authoritative = True;
- -
- - nmb->header.qdcount = 0;
- - nmb->header.ancount = 1;
- - nmb->header.nscount = 0;
- - nmb->header.arcount = 0;
- - nmb->header.rcode = 0;
- -
- - bzero((char*)&nmb->question,sizeof(nmb->question));
- -
- - nmb->answers = &answers;
- - bzero((char*)nmb->answers,sizeof(*nmb->answers));
- -
- - nmb->answers->rr_name = *rr_name;
- - nmb->answers->rr_type = rr_type;
- - nmb->answers->rr_class = rr_class;
- - nmb->answers->ttl = ttl;
- -
- - if (data && len)
- - {
- - nmb->answers->rdlength = len;
- - memcpy(nmb->answers->rdata, data, len);
- - }
- -
- - p.packet_type = NMB_PACKET;
- -
- - debug_nmb_packet(&p);
- -
- - send_packet(&p);
- + default:
- + {
- + /* nothing to do but delete the dead expected-response structure */
- + /* this is normal. */
- + break;
- + }
- + }
- }
-
-
- -/****************************************************************************
- - initiate a netbios packet
- - ****************************************************************************/
- -uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
- - int nb_flags,BOOL bcast,BOOL recurse,
- - struct in_addr to_ip)
- -{
- - struct packet_struct p;
- - struct nmb_packet *nmb = &p.packet.nmb;
- - struct res_rec additional_rec;
- - char *packet_type = "unknown";
- - int opcode = -1;
- -
- - if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
- - if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
- - if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
- - if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
- -
- - DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
- - packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
- +/*******************************************************************
- + remove old name response entries
-
- - if (opcode == -1) return False;
- + XXXX retry code needs to be added, including a retry wait period and a count
- + see name_query() and name_status() for suggested implementation.
-
- - bzero((char *)&p,sizeof(p));
- + ******************************************************************/
- +void expire_netbios_response_entries()
- +{
- + struct subnet_record *d;
-
- - if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
- - (getpid()%(unsigned)100);
- - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- -
- - nmb->header.name_trn_id = name_trn_id;
- - nmb->header.opcode = opcode;
- - nmb->header.response = False;
- - nmb->header.nm_flags.bcast = bcast;
- - nmb->header.nm_flags.recursion_available = CanRecurse;
- - nmb->header.nm_flags.recursion_desired = recurse;
- - nmb->header.nm_flags.trunc = False;
- - nmb->header.nm_flags.authoritative = False;
- - nmb->header.rcode = 0;
- - nmb->header.qdcount = 1;
- - nmb->header.ancount = 0;
- - nmb->header.nscount = 0;
- - nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
- -
- - make_nmb_name(&nmb->question.question_name,name,name_type,scope);
- -
- - nmb->question.question_type = quest_type;
- - nmb->question.question_class = 0x1;
- -
- - if (quest_type == NMB_REG || quest_type == NMB_REL)
- + for (d = subnetlist; d; d = d->next)
- + {
- + struct response_record *n, *nextn;
- +
- + for (n = d->responselist; n; n = nextn)
- {
- - nmb->additional = &additional_rec;
- - bzero((char *)nmb->additional,sizeof(*nmb->additional));
- -
- - nmb->additional->rr_name = nmb->question.question_name;
- - nmb->additional->rr_type = nmb->question.question_type;
- - nmb->additional->rr_class = nmb->question.question_class;
- -
- - nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
- - nmb->additional->rdlength = 6;
- - nmb->additional->rdata[0] = nb_flags;
- - putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
- + nextn = n->next;
- +
- + if (n->repeat_time <= time(NULL))
- + {
- + if (n->repeat_count > 0)
- + {
- + /* resend the entry */
- + initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
- + n->name.name, n->name.name_type,
- + n->nb_flags, n->bcast, n->recurse, n->send_ip);
- +
- + n->repeat_time += n->repeat_interval; /* XXXX ms needed */
- + n->repeat_count--;
- +
- + }
- + else
- + {
- + DEBUG(4,("timeout response %d for %s %s\n",
- + n->response_id, namestr(&n->name),
- + inet_ntoa(n->send_ip)));
- +
- + dead_netbios_entry (d,n); /* process the non-response */
- + remove_response_record(d,n); /* remove the non-response */
- +
- + continue;
- + }
- + }
- }
- -
- - p.ip = to_ip;
- - p.port = NMB_PORT;
- - p.fd = fd;
- - p.timestamp = time(NULL);
- - p.packet_type = NMB_PACKET;
- -
- - if (!send_packet(&p))
- - return(0);
- -
- - return(name_trn_id);
- + }
- }
-
-
- @@ -241,10 +221,18 @@
- name server instead, if it exists. if wins is false, and there has been no
- WINS server specified, the packet will NOT be sent.
- ****************************************************************************/
- -void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
- - char *name,int name_type,int nb_flags,
- - BOOL bcast,BOOL recurse,struct in_addr to_ip)
- -{
- +struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
- + int fd,int quest_type,enum state_type state,
- + char *name,int name_type,int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip)
- +{
- + /* XXXX note: please see rfc1001.txt section 10 for details on this
- + function: it is currently inappropriate to use this - it will do
- + for now - once there is a clarification of B, M and P nodes and
- + which one samba is supposed to be
- + */
- +
- if ((!lp_wins_support()) && (*lp_wins_server()))
- {
- /* samba is not a WINS server, and we are using a WINS server */
- @@ -254,7 +242,7 @@
- if (!zero_ip(wins_ip))
- {
- bcast = False;
- - to_ip = wins_ip;
- + send_ip = wins_ip;
- }
- else
- {
- @@ -264,38 +252,11 @@
- }
- }
-
- - if (zero_ip(to_ip)) return;
- -
- - queue_netbios_packet(fd, quest_type, cmd,
- - name, name_type, nb_flags,
- - bcast, recurse, to_ip);
- -}
- -
- -/****************************************************************************
- - create a name query response record
- - **************************************************************************/
- -static struct name_response_record *
- -make_name_query_record(enum cmd_type cmd,int id,int fd,char *name,int type,
- - BOOL bcast,BOOL recurse,struct in_addr ip)
- -{
- - struct name_response_record *n;
- -
- - if (!name || !name[0]) return NULL;
- -
- - if (!(n = (struct name_response_record *)malloc(sizeof(*n))))
- - return(NULL);
- -
- - n->response_id = id;
- - n->cmd_type = cmd;
- - n->fd = fd;
- - make_nmb_name(&n->name, name, type, scope);
- - n->bcast = bcast;
- - n->recurse = recurse;
- - n->to_ip = ip;
- - n->start_time = time(NULL);
- - n->num_msgs = 0;
- + if (zero_ip(send_ip)) return NULL;
-
- - return n;
- + return queue_netbios_packet(d,fd, quest_type, state,
- + name, name_type, nb_flags, ttl,
- + bcast, recurse, send_ip, reply_to_ip);
- }
-
-
- @@ -305,310 +266,33 @@
- master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
- complete lists across a wide area network
- ****************************************************************************/
- -void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
- - int name_type,int nb_flags,BOOL bcast,BOOL recurse,
- - struct in_addr to_ip)
- -{
- - uint16 id = initiate_netbios_packet(fd, quest_type, name, name_type,
- - nb_flags, bcast, recurse, to_ip);
- - struct name_response_record *n;
- -
- - if (id == 0) return;
- -
- - if ((n =
- - make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
- - {
- - add_response_record(n);
- - }
- -}
- -
- -
- -/****************************************************************************
- - find a response in the name query response list
- - **************************************************************************/
- -struct name_response_record *find_name_query(uint16 id)
- -{
- - struct name_response_record *n;
- -
- - for (n = nameresponselist; n; n = n->next)
- - {
- - if (n->response_id == id) {
- - return n;
- - }
- - }
- -
- - return NULL;
- -}
- -
- -
- -/*******************************************************************
- - the global packet linked-list. incoming entries are added to the
- - end of this list. it is supposed to remain fairly short so we
- - won't bother with an end pointer.
- - ******************************************************************/
- -static struct packet_struct *packet_queue = NULL;
- -
- -/*******************************************************************
- - queue a packet into the packet queue
- - ******************************************************************/
- -void queue_packet(struct packet_struct *packet)
- -{
- - struct packet_struct *p;
- -
- - if (!packet_queue) {
- - packet->prev = NULL;
- - packet->next = NULL;
- - packet_queue = packet;
- - return;
- +struct response_record *queue_netbios_packet(struct subnet_record *d,
- + int fd,int quest_type,enum state_type state,char *name,
- + int name_type,int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip)
- +{
- + struct in_addr wins_ip = ipgrp;
- + struct response_record *n;
- + uint16 id = 0xffff;
- +
- + /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
- + if (ip_equal(wins_ip, send_ip)) return NULL;
- +
- + initiate_netbios_packet(&id, fd, quest_type, name, name_type,
- + nb_flags, bcast, recurse, send_ip);
- +
- + if (id == 0xffff) {
- + DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
- + return NULL;
- }
-
- - /* find the bottom */
- - for (p=packet_queue;p->next;p=p->next) ;
- -
- - p->next = packet;
- - packet->next = NULL;
- - packet->prev = p;
- -}
- -
- -/*******************************************************************
- - run elements off the packet queue till its empty
- - ******************************************************************/
- -void run_packet_queue()
- -{
- - struct packet_struct *p;
- -
- - while ((p=packet_queue))
- + if ((n = make_response_queue_record(state,id,fd,
- + quest_type,name,name_type,nb_flags,ttl,
- + bcast,recurse,send_ip,reply_to_ip)))
- {
- - switch (p->packet_type)
- - {
- - case NMB_PACKET:
- - process_nmb(p);
- - break;
- -
- - case DGRAM_PACKET:
- - process_dgram(p);
- - break;
- - }
- -
- - packet_queue = packet_queue->next;
- - if (packet_queue) packet_queue->prev = NULL;
- - free_packet(p);
- + add_response_record(d,n);
- + return n;
- }
- + return NULL;
- }
- -
- -/****************************************************************************
- - listens for NMB or DGRAM packets, and queues them
- - ***************************************************************************/
- -void listen_for_packets(BOOL run_election)
- -{
- - fd_set fds;
- - int selrtn;
- - struct timeval timeout;
- -
- - FD_ZERO(&fds);
- - FD_SET(ClientNMB,&fds);
- - FD_SET(ClientDGRAM,&fds);
- -
- - /* during elections we need to send election packets at one
- - second intervals */
- -
- - timeout.tv_sec = run_election ? 1 : NMBD_SELECT_LOOP;
- - timeout.tv_usec = 0;
- -
- - selrtn = sys_select(&fds,&timeout);
- -
- - if (FD_ISSET(ClientNMB,&fds))
- - {
- - struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
- - if (packet) {
- -#if 1
- - if (ismyip(packet->ip) &&
- - (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- - DEBUG(5,("discarding own packet from %s:%d\n",
- - inet_ntoa(packet->ip),packet->port));
- - free_packet(packet);
- - } else
- -#endif
- - {
- - queue_packet(packet);
- - }
- - }
- - }
- -
- - if (FD_ISSET(ClientDGRAM,&fds))
- - {
- - struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
- - if (packet) {
- -#if 1
- - if (ismyip(packet->ip) &&
- - (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- - DEBUG(5,("discarding own packet from %s:%d\n",
- - inet_ntoa(packet->ip),packet->port));
- - free_packet(packet);
- - } else
- -#endif
- - {
- - queue_packet(packet);
- - }
- - }
- - }
- -}
- -
- -
- -
- -/****************************************************************************
- -interpret a node status response. this is pretty hacked: we need two bits of
- -info. a) the name of the workgroup b) the name of the server. it will also
- -add all the names it finds into the namelist.
- -****************************************************************************/
- -BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
- - char *serv_name, struct in_addr ip)
- -{
- - int level = t==0x20 ? 4 : 0;
- - int numnames = CVAL(p,0);
- - BOOL found = False;
- -
- - DEBUG(level,("received %d names\n",numnames));
- -
- - p += 1;
- -
- - if (serv_name) *serv_name = 0;
- -
- - while (numnames--)
- - {
- - char qname[17];
- - int type;
- - fstring flags;
- - int nb_flags;
- -
- - BOOL group = False;
- - BOOL add = False;
- -
- - *flags = 0;
- -
- - StrnCpy(qname,p,15);
- - type = CVAL(p,15);
- - nb_flags = p[16];
- - trim_string(qname,NULL," ");
- -
- - p += 18;
- -
- - if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
- - if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
- - if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
- - if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
- - if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
- - if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
- - if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
- - if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
- - if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
- -
- - /* might as well update our namelist while we're at it */
- - if (add)
- - {
- - struct in_addr nameip;
- - enum name_source src;
- -
- - if (ismyip(ip)) {
- - nameip = ipzero;
- - src = SELF;
- - } else {
- - nameip = ip;
- - src = STATUS_QUERY;
- - }
- - add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip,True);
- - }
- -
- - /* we want the server name */
- - if (serv_name && !*serv_name && !group && t == 0)
- - {
- - StrnCpy(serv_name,qname,15);
- - serv_name[15] = 0;
- - }
- -
- - /* looking for a name and type? */
- - if (name && !found && (t == type))
- - {
- - /* take a guess at some of the name types we're going to ask for.
- - evaluate whether they are group names or no... */
- - if (((t == 0x1b || t == 0x1d ) && !group) ||
- - ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
- - {
- - found = True;
- - make_nmb_name(name,qname,type,scope);
- - }
- - }
- -
- - DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
- - }
- - DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
- - IVAL(p,20),IVAL(p,24)));
- - return found;
- -}
- -
- -
- -/****************************************************************************
- - construct and send a netbios DGRAM
- -
- - Note that this currently sends all answers to port 138. thats the
- - wrong things to do! I should send to the requestors port. XXX
- - **************************************************************************/
- -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
- - char *dstname,int src_type,int dest_type,
- - struct in_addr dest_ip,struct in_addr src_ip)
- -{
- - struct packet_struct p;
- - struct dgram_packet *dgram = &p.packet.dgram;
- - char *ptr,*p2;
- - char tmp[4];
- -
- - bzero((char *)&p,sizeof(p));
- -
- - dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
- - dgram->header.flags.node_type = M_NODE;
- - dgram->header.flags.first = True;
- - dgram->header.flags.more = False;
- - dgram->header.dgm_id = name_trn_id++;
- - dgram->header.source_ip = src_ip;
- - dgram->header.source_port = DGRAM_PORT;
- - dgram->header.dgm_length = 0; /* let build_dgram() handle this */
- - dgram->header.packet_offset = 0;
- -
- - make_nmb_name(&dgram->source_name,srcname,src_type,scope);
- - make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
- -
- - ptr = &dgram->data[0];
- -
- - /* now setup the smb part */
- - ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
- - memcpy(tmp,ptr,4);
- - set_message(ptr,17,17 + len,True);
- - memcpy(ptr,tmp,4);
- -
- - CVAL(ptr,smb_com) = SMBtrans;
- - SSVAL(ptr,smb_vwv1,len);
- - SSVAL(ptr,smb_vwv11,len);
- - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- - SSVAL(ptr,smb_vwv13,3);
- - SSVAL(ptr,smb_vwv14,1);
- - SSVAL(ptr,smb_vwv15,1);
- - SSVAL(ptr,smb_vwv16,2);
- - p2 = smb_buf(ptr);
- - strcpy(p2,mailslot);
- - p2 = skip_string(p2,1);
- -
- - memcpy(p2,buf,len);
- - p2 += len;
- -
- - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
- -
- - p.ip = dest_ip;
- - p.port = DGRAM_PORT;
- - p.fd = ClientDGRAM;
- - p.timestamp = time(NULL);
- - p.packet_type = DGRAM_PACKET;
- -
- - return(send_packet(&p));
- -}
- -
- -
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameresp.doc samba-1.9.16alpha11/source/nameresp.doc
- --- samba-1.9.16alpha10/source/nameresp.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameresp.doc Thu Jul 18 20:53:15 1996
- @@ -0,0 +1,151 @@
- +the netbios expected response code is a key part of samba's NetBIOS
- +handling capabilities. it allows samba to carry on dealing with
- +other things while expecting a response from one or more hosts.
- +
- +this allows samba to simultaneously deal with registering its names
- +with another WINS server, register its names on its local subnets,
- +query any hosts that have registered with samba in its capacity as
- +a WINS server, and at a later date it will be also be able handle
- +END-NODE CHALLENGES (see rfc1001.txt 15.2.2.2 and 15.2.2.3 - secured
- +NBNS functionality).
- +
- +all at once!
- +
- +when a netbios packet is sent out by samba and it expects a response,
- +a record of all the relevant information is kept (most importantly,
- +the unique transaction id associated which will come back to us in
- +a response packet is recorded, and also recorded is the reason that
- +the original packet was sent out by samba in the first place!).
- +
- +if a response is received, then the unique transaction identifier
- +returned in the response packet is searched for in the expected
- +response records. the record indicates why the initial request was
- +made (and therefore the type of response can be verified) and
- +appropriate action can be taken.
- +
- +when no responses, after a number of retries, are not received, then
- +samba may take appropriate action. this is a crucial part of samba's
- +operation: for a key number of NetBIOS operations, no response is an
- +implicit positive response.
- +
- +module nameresp deals with the initial transmission, re-transmission
- +and time-out of netbios response records.
- +
- +module namedbresp deals with the maintenance of the list of expected
- +responses - creation, finding and removal.
- +
- +
- +/*************************************************************************
- + queue_netbios_packet()
- + *************************************************************************/
- +
- +this function is responsible for sending out a netbios packet, and then
- +making a record of the information that was sent out. a response will
- +be expected later (or not, as the case may be).
- +
- +if a response is received, response_netbios_packet() will deal with it.
- +otherwise, it will be dealt with in expire_netbios_response_entries().
- +
- +
- +/*************************************************************************
- + queue_netbios_pkt_wins()
- + *************************************************************************/
- +
- +this function is a wrapper around queue_netbios_packet(). there is
- +some confusion about B, M and P nodes (see rfc1001.txt section 10) -
- +confusion introduced by luke :-) - which needs sorting out.
- +
- +for example, rfc1001.txt 15.2.3 - an M node must attempt to register a
- +name first as a B node, then attempt to register as an M node. negative
- +responses on either of these attempts is a failure to register the
- +name.
- +
- +this is NOT the case with a P node.
- +
- +
- +/*************************************************************************
- + expire_netbios_response_entries()
- + *************************************************************************/
- +
- +this function is responsible for dealing with queued response records
- +that have not received a response packet matching their unique
- +transaction id.
- +
- +if the retry count for any record is non-zero, and its time-out period
- +has expired, the retry count is reduced, the time-out period is stepped
- +forward and the packet is re-transmitted (from the information stored
- +in the queued response record) with the same unique transaction id of
- +the initial attempt at soliciting a response.
- +
- +if the retry count is zero, then the packet is assumed to have expired.
- +dead_netbios_entry() is called to deal with the possibility of an error
- +or a problem (or in certain instances, no answer is an implicit
- +positive response!).
- +
- +the expected response record is then deleted, and the number of expected
- +responses reduced. when this count gets to zero, listen_for_packets()
- +will no longer time-out for 1 second on account of expecting response
- +packets.
- +
- +
- +/*************************************************************************
- + dead_netbios_entry()
- + *************************************************************************/
- +
- +this function is responsible for dealing with the case when a NetBIOS
- +response to a packet sent out by samba was not received. for certain
- +transactions, this may be normal. for others, under certain conditions
- +it may constitute either an error or a problem with or failure of one
- +or more hosts.
- +
- +- NAME_QUERY_CONFIRM
- +
- +when a samba 'state' of type NAME_QUERY_CONFIRM is sent, a response
- +may or may not be forthcoming. if no response is received to a unique
- +name, then the record is removed from samba's WINS database. non-unique
- +names are simply expected to die off on a time-to-live basis (see
- +rfc1001.txt 15.1.3.4)
- +
- +query_refresh_names() issues this samba 'state'
- +response_name_query_sync() deals with responses to NAME_QUERY_CONFIRM.
- +
- +- NAME_QUERY_MST_CHK
- +
- +when a samba 'state' of type NAME_QUERY_MST_CHK is sent, and a response
- +is not received, this implies that a master browser will have failed.
- +remedial action may need to be taken, for example if samba is a member
- +of that workgroup and it is also a potential master browser it could
- +force an election.
- +
- +check_master_browser() issues this samba 'state'.
- +response_process() does nothing if a response is received. this is normal.
- +
- +- NAME_RELEASE
- +
- +when a samba 'state' of type NAME_RELEASE is sent, and a response is
- +not received, it is assumed to be acceptable to release the name. if the
- +original response was sent to another WINS server, then that WINS server
- +may be inaccessible or may have failed. if so, then at a later date
- +samba should take this into account (see rfc1001.txt 10.3).
- +
- +remove_name_entry() issues this samba 'state'
- +response_name_rel() deals with responses to NAME_RELEASE.
- +
- +- NAME_REGISTER
- +
- +when a samba 'state' of type NAME_REGISTER is sent, and a response is
- +not received, if the registration was done by broadcast, it is assumed
- +that there are no objections to the registration of this name, and samba
- +adds the name to the appropriate subnet record name database. if the
- +registration was point-to-point (i.e with another WINS server) then that
- +WINS server may be inaccessible or may have failed. if so, then at a later
- +date samba should take this into account (see rfc1001.txt 10.3).
- +
- +add_my_name_entry() issues this samba 'state'
- +response_name_reg() deals with responses to NAME_REGISTER.
- +
- +no action is taken for any other kinds of samba 'states' if a response
- +is not received. this is not to say that action may not be appropriate,
- +just that it's not been looked at yet :-)
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.c samba-1.9.16alpha11/source/nameserv.c
- --- samba-1.9.16alpha10/source/nameserv.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/nameserv.c Thu Jul 18 20:53:15 1996
- @@ -2,7 +2,7 @@
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- - Copyright (C) Andrew Tridgell 1994-1995
- + Copyright (C) Andrew Tridgell 1994-1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- @@ -18,225 +18,151 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- + Module name: nameserv.c
- +
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- + 04 jul 96: lkcl@pires.co.uk
- + module nameserv contains name server management functions
- */
-
- #include "includes.h"
-
- extern int ClientNMB;
- -extern int ClientDGRAM;
-
- extern int DEBUGLEVEL;
-
- extern pstring scope;
- -extern BOOL CanRecurse;
- extern pstring myname;
- +extern pstring ServerComment;
- extern struct in_addr ipzero;
- extern struct in_addr ipgrp;
-
- -/* netbios names database */
- -struct name_record *namelist;
- -
- -#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
- +extern struct subnet_record *subnetlist;
-
-
- /****************************************************************************
- - true if two netbios names are equal
- -****************************************************************************/
- -static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
- -{
- - if (n1->name_type != n2->name_type) return(False);
- -
- - return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
- -}
- -
- -/****************************************************************************
- - add a netbios name into the namelist
- - **************************************************************************/
- -static void add_name(struct name_record *n)
- -{
- - struct name_record *n2;
- -
- - if (!namelist)
- - {
- - namelist = n;
- - n->prev = NULL;
- - n->next = NULL;
- - return;
- - }
- + remove an entry from the name list
-
- - for (n2 = namelist; n2->next; n2 = n2->next) ;
- + note: the name will _always_ be removed: it's just a matter of when.
- + XXXX at present, the name is removed _even_ if a WINS server says keep it.
-
- - n2->next = n;
- - n->next = NULL;
- - n->prev = n2;
- -}
- -
- -/****************************************************************************
- - remove a name from the namelist. The pointer must be an element just
- - retrieved
- - **************************************************************************/
- -void remove_name(struct name_record *n)
- + ****************************************************************************/
- +void remove_name_entry(struct subnet_record *d, char *name,int type)
- {
- - struct name_record *nlist = namelist;
- + /* XXXX BUG: if samba is offering WINS support, it should still broadcast
- + a de-registration packet to the local subnet before removing the
- + name from its local-subnet name database. */
-
- - while (nlist && nlist != n) nlist = nlist->next;
- + struct name_record n;
- + struct name_record *n2=NULL;
- +
- + make_nmb_name(&n.name,name,type,scope);
-
- - if (nlist)
- + if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero)))
- {
- - if (nlist->next) nlist->next->prev = nlist->prev;
- - if (nlist->prev) nlist->prev->next = nlist->next;
- - free(nlist);
- - }
- -}
- + /* check name isn't already being de-registered */
- + if (NAME_DEREG(n2->nb_flags))
- + return;
-
- + /* mark the name as in the process of deletion. */
- + n2->nb_flags &= NB_DEREG;
- + }
-
- -/****************************************************************************
- - find a name in the domain database namelist
- - search can be:
- - FIND_SELF - look for names the samba server has added for itself
- - FIND_GLOBAL - the name can be anyone. first look on the client's
- - subnet, then the server's subnet, then all subnets.
- - **************************************************************************/
- -static struct name_record *find_name_search(struct nmb_name *name,
- - enum name_search search,
- - struct in_addr ip)
- -{
- - struct name_record *ret;
- -
- - for (ret = namelist; ret; ret = ret->next)
- + if (ip_equal(d->bcast_ip, ipgrp))
- + {
- + if (lp_wins_support())
- {
- - if (!name_equal(&ret->name,name)) continue;
- -
- - if (search == FIND_SELF && ret->source != SELF) continue;
- -
- - return ret;
- + /* we are a WINS server. */
- + /* XXXX assume that if we are a WINS server that we are therefore
- + not pointing to another WINS server as well. this may later NOT
- + actually be true
- + */
- + remove_netbios_name(d,name,type,SELF,ipzero);
- + }
- + else
- + {
- + /* not a WINS server: cannot just remove our own names: we have to
- + release them on the network first. ask permission from the WINS
- + server, or if no reply is received, then we can remove the name */
- +
- + queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
- + name, type, 0, 0,
- + False, True, ipzero, ipzero);
- }
- -
- - return NULL;
- + }
- + else
- + {
- + /* local interface: cannot just remove our own names: we have to
- + release them on the network first. once no reply is received,
- + then we can remove the name. */
- +
- + queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
- + name, type, 0, 0,
- + True, True, d->bcast_ip, d->bcast_ip);
- + }
- }
-
-
- /****************************************************************************
- - dump a copy of the name table
- - **************************************************************************/
- -void dump_names(void)
- -{
- - struct name_record *n;
- - time_t t = time(NULL);
- -
- - DEBUG(3,("Dump of local name table:\n"));
- + add an entry to the name list
-
- - for (n = namelist; n; n = n->next)
- - {
- - DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n",
- - namestr(&n->name),
- - inet_ntoa(n->ip),
- - n->death_time?n->death_time-t:0,
- - n->nb_flags));
- - }
- -}
- -
- + big note: our name will _always_ be added (if there are no objections).
- + it's just a matter of when this will be done (e.g after a time-out).
-
- -/****************************************************************************
- - remove an entry from the name list
- ****************************************************************************/
- -void remove_netbios_name(char *name,int type, enum name_source source,
- - struct in_addr ip)
- +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
- {
- - struct nmb_name nn;
- - struct name_record *n;
- -
- - make_nmb_name(&nn, name, type, scope);
- - n = find_name_search(&nn, FIND_GLOBAL, ip);
- -
- - if (n && n->source == source) remove_name(n);
- -}
- + BOOL re_reg = False;
- + struct nmb_name n;
-
- + if (!d) return;
-
- -/****************************************************************************
- - add an entry to the name list
- - ****************************************************************************/
- -struct name_record *add_netbios_entry(char *name, int type, int nb_flags,
- - int ttl,
- - enum name_source source,
- - struct in_addr ip,
- - BOOL new_only)
- -{
- - struct name_record *n;
- - struct name_record *n2=NULL;
- -
- - n = (struct name_record *)malloc(sizeof(*n));
- - if (!n) return(NULL);
- + /* not that it particularly matters, but if the SELF name already exists,
- + it must be re-registered, rather than just registered */
-
- - bzero((char *)n,sizeof(*n));
- + make_nmb_name(&n, name, type, scope);
- + if (find_name(d->namelist, &n, SELF))
- + re_reg = True;
-
- - make_nmb_name(&n->name,name,type,scope);
- + /* XXXX BUG: if samba is offering WINS support, it should still add the
- + name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
- + regarding the point about M-nodes. */
-
- - if ((n2 = find_name_search(&n->name, FIND_GLOBAL, new_only?ipzero:ip)))
- + if (ip_equal(d->bcast_ip, ipgrp))
- {
- - free(n);
- - if (new_only || (n2->source==SELF && source!=SELF)) return n2;
- - n = n2;
- - }
- -
- - if (ttl) n->death_time = time(NULL)+ttl*3;
- - n->ip = ip;
- - n->nb_flags = nb_flags;
- - n->source = source;
- -
- - if (!n2) add_name(n);
- -
- - DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
- - namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
- -
- - return(n);
- -}
- -
- -
- -/****************************************************************************
- - remove an entry from the name list
- - ****************************************************************************/
- -void remove_name_entry(char *name,int type)
- -{
- - if (lp_wins_support())
- + if (lp_wins_support())
- {
- /* we are a WINS server. */
- - remove_netbios_name(name,type,SELF,ipzero);
- + /* XXXX assume that if we are a WINS server that we are therefore
- + not pointing to another WINS server as well. this may later NOT
- + actually be true
- + */
- +
- + DEBUG(4,("samba as WINS server adding: "));
- + /* this will call add_netbios_entry() */
- + name_register_work(d, name, type, nb_flags,0, ipzero, False);
- + }
- + else
- + {
- + /* a time-to-live allows us to refresh this name with the WINS server. */
- + queue_netbios_pkt_wins(d,ClientNMB,
- + re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- + name, type, nb_flags, GET_TTL(0),
- + False, True, ipzero, ipzero);
- }
- + }
- else
- - {
- - struct in_addr ip;
- - ip = ipzero;
- -
- - queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
- - name, type, 0,
- - False, True, ip);
- - }
- -}
- -
- -
- -/****************************************************************************
- - add an entry to the name list
- - ****************************************************************************/
- -void add_name_entry(char *name,int type,int nb_flags)
- -{
- - /* always add our own entries */
- - add_netbios_entry(name,type,nb_flags,0,SELF,ipzero,False);
- -
- - if (!lp_wins_support())
- - {
- - struct in_addr ip;
- - ip = ipzero;
- -
- - queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
- - name, type, nb_flags,
- - False, True, ip);
- - }
- + {
- + /* broadcast the packet, but it comes from ipzero */
- + queue_netbios_packet(d,ClientNMB,
- + re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- + name, type, nb_flags, GET_TTL(0),
- + True, True, d->bcast_ip, ipzero);
- + }
- }
-
-
- @@ -245,815 +171,161 @@
- **************************************************************************/
- void add_my_names(void)
- {
- - struct in_addr ip;
- + BOOL wins = lp_wins_support();
- + struct subnet_record *d;
-
- - ip = ipzero;
- -
- - add_name_entry(myname,0x20,NB_ACTIVE);
- - add_name_entry(myname,0x03,NB_ACTIVE);
- - add_name_entry(myname,0x00,NB_ACTIVE);
- - add_name_entry(myname,0x1f,NB_ACTIVE);
- -
- - add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip,False);
- - add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False);
- - add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False);
- -
- - if (lp_wins_support()) {
- - /* the 0x1c name gets added by any WINS server it seems */
- - add_name_entry(my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
- - }
- -}
- -
- -/****************************************************************************
- - remove all the samba names... from a WINS server if necessary.
- - **************************************************************************/
- -void remove_my_names()
- -{
- - struct name_record *n;
- -
- - for (n = namelist; n; n = n->next)
- - {
- - if (n->source == SELF)
- - {
- - /* get all SELF names removed from the WINS server's database */
- - remove_name_entry(n->name.name, n->name.name_type);
- - }
- - }
- -}
- -
- -
- -/*******************************************************************
- - refresh my own names
- - ******************************************************************/
- -void refresh_my_names(time_t t)
- -{
- - static time_t lasttime = 0;
- + struct in_addr ip = ipzero;
-
- - if (t - lasttime < REFRESH_TIME)
- - return;
- - lasttime = t;
- + /* each subnet entry, including WINS pseudo-subnet, has SELF names */
-
- - add_my_names();
- -}
- + /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
- + there would be yet _another_ for-loop, this time on the transport type
- + */
-
- -/*******************************************************************
- - expires old names in the namelist
- - ******************************************************************/
- -void expire_names(time_t t)
- -{
- - struct name_record *n;
- - struct name_record *next;
- -
- - /* expire old names */
- - for (n = namelist; n; n = next)
- - {
- - if (n->death_time && n->death_time < t)
- - {
- - DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
- -
- - next = n->next;
- -
- - if (n->prev) n->prev->next = n->next;
- - if (n->next) n->next->prev = n->prev;
- -
- - if (namelist == n) namelist = n->next;
- -
- - free(n);
- - }
- - else
- - {
- - next = n->next;
- - }
- - }
- -}
- -
- -
- -/****************************************************************************
- - response for a reg release received
- - **************************************************************************/
- -void response_name_release(struct packet_struct *p)
- -{
- - struct nmb_packet *nmb = &p->packet.nmb;
- - char *name = nmb->question.question_name.name;
- - int type = nmb->question.question_name.name_type;
- -
- - DEBUG(4,("response name release received\n"));
- -
- - if (nmb->header.rcode == 0 && nmb->answers->rdata)
- - {
- - struct in_addr found_ip;
- - putip((char*)&found_ip,&nmb->answers->rdata[2]);
- -
- - if (ismyip(found_ip))
- - {
- - remove_netbios_name(name,type,SELF,found_ip);
- - }
- - }
- - else
- - {
- - DEBUG(1,("name registration for %s rejected!\n",
- - namestr(&nmb->question.question_name)));
- - }
- -}
- -
- -
- -/****************************************************************************
- - reply to a name release
- - ****************************************************************************/
- -void reply_name_release(struct packet_struct *p)
- -{
- - struct nmb_packet *nmb = &p->packet.nmb;
- - struct in_addr ip;
- - int rcode=0;
- - int opcode = nmb->header.opcode;
- - int nb_flags = nmb->additional->rdata[0];
- - BOOL bcast = nmb->header.nm_flags.bcast;
- - struct name_record *n;
- - char rdata[6];
- -
- - putip((char *)&ip,&nmb->additional->rdata[2]);
- -
- - DEBUG(3,("Name release on name %s rcode=%d\n",
- - namestr(&nmb->question.question_name),rcode));
- -
- - n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
- -
- - /* XXXX under what conditions should we reject the removal?? */
- - if (n && n->nb_flags == nb_flags)
- - {
- - /* success = True;
- - rcode = 6; */
- -
- - remove_name(n);
- - n = NULL;
- - }
- -
- - if (bcast) return;
- -
- - rdata[0] = nb_flags;
- - rdata[1] = 0;
- - putip(&rdata[2],(char *)&ip);
- -
- - /* Send a NAME RELEASE RESPONSE */
- - reply_netbios_packet(p,nmb->header.name_trn_id,
- - rcode,opcode,True,
- - &nmb->question.question_name,
- - nmb->question.question_type,
- - nmb->question.question_class,
- - 0,
- - rdata, 6);
- -}
- + for (d = subnetlist; d; d = d->next)
- + {
- + BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
-
- + if (!d->my_interface && !wins_iface) continue;
-
- -/****************************************************************************
- - response for a reg request received
- - **************************************************************************/
- -void response_name_reg(struct packet_struct *p)
- -{
- - struct nmb_packet *nmb = &p->packet.nmb;
- - char *name = nmb->question.question_name.name;
- - int type = nmb->question.question_name.name_type;
- -
- - DEBUG(4,("response name registration received!\n"));
- -
- - if (nmb->header.rcode == 0 && nmb->answers->rdata)
- - {
- - int nb_flags = nmb->answers->rdata[0];
- - struct in_addr found_ip;
- - int ttl = nmb->answers->ttl;
- - enum name_source source = REGISTER;
- -
- - putip((char*)&found_ip,&nmb->answers->rdata[2]);
- -
- - if (ismyip(found_ip)) source = SELF;
- -
- - add_netbios_entry(name,type,nb_flags,ttl,source,found_ip,True);
- + add_my_name_entry(d, myname,0x20,NB_ACTIVE);
- + add_my_name_entry(d, myname,0x03,NB_ACTIVE);
- + add_my_name_entry(d, myname,0x00,NB_ACTIVE);
- + add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
- +
- + /* these names are added permanently (ttl of zero) and will NOT be
- + refreshed with the WINS server */
- + add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
- + add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
- + add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
- +
- + if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
- + /* XXXX the 0x1c is apparently something to do with domain logons */
- + add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
- }
- - else
- + }
- + if (lp_domain_master() && (d = find_subnet(ipgrp)))
- + {
- + struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
- + if (work && work->state == MST_NONE)
- {
- - DEBUG(1,("name registration for %s rejected!\n",
- - namestr(&nmb->question.question_name)));
- + work->state = MST_DOMAIN_NONE;
- + become_master(d, work);
- }
- + }
- }
-
-
- /****************************************************************************
- - reply to a reg request
- + remove all the samba names... from a WINS server if necessary.
- **************************************************************************/
- -void reply_name_reg(struct packet_struct *p)
- +void remove_my_names()
- {
- - struct nmb_packet *nmb = &p->packet.nmb;
- - struct nmb_name *question = &nmb->question.question_name;
- -
- - struct nmb_name *reply_name = question;
- - char *qname = question->name;
- - int name_type = question->name_type;
- - int name_class = nmb->question.question_class;
- -
- - BOOL bcast = nmb->header.nm_flags.bcast;
- -
- - int ttl = GET_TTL(nmb->additional->ttl);
- - int nb_flags = nmb->additional->rdata[0];
- - BOOL group = NAME_GROUP(nb_flags);
- - int rcode = 0;
- - int opcode = nmb->header.opcode;
- -
- - struct name_record *n = NULL;
- - BOOL success = True;
- - BOOL recurse = True; /* true if samba replies yes/no: false if caller */
- - /* must challenge the current owner */
- - char rdata[6];
- -
- - struct in_addr ip, from_ip;
- -
- - DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
- - namestr(question),inet_ntoa(ip),rcode));
- -
- - putip((char *)&from_ip,&nmb->additional->rdata[2]);
- - ip = from_ip;
- -
- - if (group)
- - {
- - /* apparently we should return 255.255.255.255 for group queries
- - (email from MS) */
- - ip = ipgrp;
- - }
- -
- - /* see if the name already exists */
- - n = find_name_search(question, FIND_GLOBAL, from_ip);
- -
- - if (n)
- - {
- - if (!group) /* unique names */
- - {
- - if (n->source == SELF || NAME_GROUP(n->nb_flags))
- - {
- - /* no-one can register one of samba's names, nor can they
- - register a name that's a group name as a unique name */
- -
- - rcode = 6;
- - success = False;
- - }
- - else if(!ip_equal(ip, n->ip))
- - {
- - /* hm. this unique name doesn't belong to them. */
- -
- - /* XXXX rfc1001.txt says:
- - * if we are doing secured WINS, we must send a Wait-Acknowledge
- - * packet (WACK) to the person who wants the name, then do a
- - * name query on the person who currently owns the unique name.
- - * if the current owner is alive, the person who wants the name
- - * can't have it. if they are not alive, they can.
- - *
- - * if we are doing non-secure WINS (which is much simpler) then
- - * we send a message to the person wanting the name saying 'he
- - * owns this name: i don't want to hear from you ever again
- - * until you've checked with him if you can have it!'. we then
- - * abandon the registration. once the person wanting the name
- - * has checked with the current owner, they will repeat the
- - * registration packet if the current owner is dead or doesn't
- - * want the name.
- - */
- -
- - /* non-secured WINS implementation: caller is responsible
- - for checking with current owner of name, then getting back
- - to us... IF current owner no longer owns the unique name */
- -
- - rcode = 0;
- - success = False;
- - recurse = False;
- -
- - /* we inform on the current owner to the caller (which is
- - why it's non-secure */
- -
- - reply_name = &n->name;
- -
- - /* name_type = ?;
- - name_class = ?;
- - XXXX sorry, guys: i really can't see what name_type
- - and name_class should be set to according to rfc1001 */
- - }
- - else
- - {
- - /* XXXX removed code that checked with the owner of a name */
- -
- - n->ip = ip;
- - n->death_time = ttl?p->timestamp+ttl*3:0;
- - DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
- - }
- - }
- - else
- - {
- - /* refresh the name */
- - if (n->source != SELF)
- - {
- - n->death_time = ttl?p->timestamp + ttl*3:0;
- - }
- - }
- - }
- - else
- - {
- - /* add the name to our subnet/name database */
- - n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip,True);
- - }
- -
- - if (bcast) return;
- -
- - if (success)
- - {
- - update_from_reg(nmb->question.question_name.name,
- - nmb->question.question_name.name_type, from_ip);
- - }
- -
- - rdata[0] = nb_flags;
- - rdata[1] = 0;
- - putip(&rdata[2],(char *)&ip);
- -
- - /* Send a NAME REGISTRATION RESPONSE (pos/neg)
- - or and END-NODE CHALLENGE REGISTRATION RESPONSE */
- - reply_netbios_packet(p,nmb->header.name_trn_id,
- - rcode,opcode,recurse,
- - reply_name, name_type, name_class,
- - ttl,
- - rdata, 6);
- -}
- + struct subnet_record *d;
-
- -
- -/****************************************************************************
- - reply to a name status query
- - ****************************************************************************/
- -void reply_name_status(struct packet_struct *p)
- -{
- - struct nmb_packet *nmb = &p->packet.nmb;
- - char *qname = nmb->question.question_name.name;
- - int ques_type = nmb->question.question_name.name_type;
- - char rdata[MAX_DGRAM_SIZE];
- - char *countptr, *buf, *bufend;
- - int names_added;
- - struct name_record *n;
- -
- - DEBUG(3,("Name status for name %s %s\n",
- - namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
- -
- - n = find_name_search(&nmb->question.question_name,FIND_GLOBAL, p->ip);
- -
- - if (!n) return;
- -
- - /* XXXX hack, we should calculate exactly how many will fit */
- - bufend = &rdata[MAX_DGRAM_SIZE] - 18;
- - countptr = buf = rdata;
- - buf += 1;
- -
- - names_added = 0;
- -
- - for (n = namelist ; n && buf < bufend; n = n->next)
- - {
- - int name_type = n->name.name_type;
- -
- - if (n->source != SELF) continue;
- -
- - /* start with first bit of putting info in buffer: the name */
- -
- - bzero(buf,18);
- - sprintf(buf,"%-15.15s",n->name.name);
- - strupper(buf);
- -
- - /* now check if we want to exclude other workgroup names
- - from the response. if we don't exclude them, windows clients
- - get confused and will respond with an error for NET VIEW */
- -
- - if (name_type >= 0x1b && name_type <= 0x20 &&
- - ques_type >= 0x1b && ques_type <= 0x20)
- + for (d = subnetlist; d; d = d->next)
- {
- - if (!strequal(qname, n->name.name)) continue;
- - }
- -
- - /* carry on putting name info in buffer */
- -
- - buf[15] = name_type;
- - buf[16] = n->nb_flags;
- -
- - buf += 18;
- -
- - names_added++;
- - }
- -
- - SCVAL(countptr,0,names_added);
- -
- - /* XXXXXXX we should fill in more fields of the statistics structure */
- - bzero(buf,64);
- - {
- - extern int num_good_sends,num_good_receives;
- - SIVAL(buf,20,num_good_sends);
- - SIVAL(buf,24,num_good_receives);
- - }
- -
- - SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
- -
- - buf += 64;
- -
- - /* Send a POSITIVE NAME STATUS RESPONSE */
- - reply_netbios_packet(p,nmb->header.name_trn_id,
- - 0,0,True,
- - &nmb->question.question_name,
- - nmb->question.question_type,
- - nmb->question.question_class,
- - 0,
- - rdata,PTR_DIFF(buf,rdata));
- -}
- + struct name_record *n, *next;
-
- + for (n = d->namelist; n; n = next)
- + {
- + next = n->next;
- + if (n->source == SELF)
- + {
- + /* get all SELF names removed from the WINS server's database */
- + /* XXXX note: problem occurs if this removes the wrong one! */
-
- -/***************************************************************************
- - reply to a name query
- - ****************************************************************************/
- -static struct name_record *search_for_name(struct nmb_name *question,
- - struct in_addr ip, int Time,
- - enum name_search search)
- -{
- - int name_type = question->name_type;
- - char *qname = question->name;
- - BOOL dns_type = name_type == 0x20 || name_type == 0;
- -
- - struct name_record *n;
- -
- - DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
- -
- - /* first look up name in cache. use ip as well as name to locate it */
- - n = find_name_search(question,search,ip);
- -
- - /* now try DNS lookup. */
- - if (!n)
- - {
- - struct in_addr dns_ip;
- - unsigned long a;
- -
- - /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
- - if (!dns_type)
- - {
- - DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
- - return NULL;
- - }
- -
- - /* look it up with DNS */
- - a = interpret_addr(qname);
- -
- - putip((char *)&dns_ip,(char *)&a);
- -
- - if (!a)
- - {
- - /* no luck with DNS. We could possibly recurse here XXXX */
- - /* if this isn't a bcast then we should send a negative reply XXXX */
- - DEBUG(3,("no recursion\n"));
- - add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,True);
- - return NULL;
- + remove_name_entry(d,n->name.name, n->name.name_type);
- + }
- + }
- }
- -
- - /* add it to our cache of names. give it 2 hours in the cache */
- - n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,True);
- -
- - /* failed to add it? yikes! */
- - if (!n) return NULL;
- - }
- -
- - /* is our entry already dead? */
- - if (n->death_time)
- - {
- - if (n->death_time < Time) return False;
- - }
- -
- - /* it may have been an earlier failure */
- - if (n->source == DNSFAIL)
- - {
- - DEBUG(3,("DNSFAIL\n"));
- - return NULL;
- - }
- -
- - DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));
- -
- - return n;
- }
-
-
- -
- -/***************************************************************************
- - reply to a name query
- - ****************************************************************************/
- -void reply_name_query(struct packet_struct *p)
- +/*******************************************************************
- + refresh my own names
- + ******************************************************************/
- +void refresh_my_names(time_t t)
- {
- - struct nmb_packet *nmb = &p->packet.nmb;
- - struct nmb_name *question = &nmb->question.question_name;
- - int name_type = question->name_type;
- - BOOL dns_type = name_type == 0x20 || name_type == 0;
- - BOOL bcast = nmb->header.nm_flags.bcast;
- - int ttl=0;
- - int rcode = 0;
- - int nb_flags = 0;
- - struct in_addr retip;
- - char rdata[6];
- - BOOL success = True;
- - struct name_record *n;
- - enum name_search search = (dns_type || name_type == 0x1b) ?
- - FIND_GLOBAL : FIND_SELF;
- + struct subnet_record *d;
-
- - DEBUG(3,("Name query "));
- -
- - if ((n = search_for_name(question,p->ip,p->timestamp, search)))
- - {
- - /* don't respond to broadcast queries unless the query is for
- - a name we own or it is for a Primary Domain Controller name */
- - if (bcast && n->source != SELF && name_type != 0x1b)
- - {
- - if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
- - /* never reply with a negative response to broadcast queries */
- - return;
- - }
- - }
- -
- - /* name is directed query, or it's self, or it's a PDC type name */
- - ttl = n->death_time - p->timestamp;
- - retip = n->ip;
- - nb_flags = n->nb_flags;
- - }
- - else
- - {
- - if (bcast) return; /* never reply negative response to bcasts */
- - success = False;
- - }
- -
- - /* if the IP is 0 then substitute my IP */
- - if (zero_ip(retip)) retip = *iface_ip(p->ip);
- -
- - if (success)
- - {
- - rcode = 0;
- - DEBUG(3,("OK %s\n",inet_ntoa(retip)));
- - }
- - else
- - {
- - rcode = 3;
- - DEBUG(3,("UNKNOWN\n"));
- - }
- -
- - if (success)
- + for (d = subnetlist; d; d = d->next)
- + {
- + struct name_record *n;
- +
- + for (n = d->namelist; n; n = n->next)
- {
- - rdata[0] = nb_flags;
- - rdata[1] = 0;
- - putip(&rdata[2],(char *)&retip);
- + /* each SELF name has an individual time to be refreshed */
- + if (n->source == SELF && n->refresh_time < time(NULL) &&
- + n->death_time != 0)
- + {
- + add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
- + }
- }
- -
- - reply_netbios_packet(p,nmb->header.name_trn_id,
- - rcode,0,True,
- - &nmb->question.question_name,
- - nmb->question.question_type,
- - nmb->question.question_class,
- - ttl,
- - rdata, success ? 6 : 0);
- + }
- }
-
-
- +/*******************************************************************
- + queries names occasionally. an over-cautious, non-trusting WINS server!
-
- -/****************************************************************************
- -response from a name query
- -****************************************************************************/
- -static void response_netbios_packet(struct packet_struct *p)
- + this function has been added because nmbd could be restarted. it
- + is generally a good idea to check all the names that have been
- + reloaded from file.
- +
- + XXXX which names to poll and which not can be refined at a later date.
- + ******************************************************************/
- +void query_refresh_names(void)
- {
- - struct nmb_packet *nmb = &p->packet.nmb;
- - struct nmb_name *question = &nmb->question.question_name;
- - char *qname = question->name;
- - BOOL bcast = nmb->header.nm_flags.bcast;
- - struct name_response_record *n;
- + struct name_record *n;
- + struct subnet_record *d = find_subnet(ipgrp);
-
- - if (nmb->answers == NULL)
- - {
- - DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
- - inet_ntoa(p->ip),
- - BOOLSTR(bcast)));
- - return;
- - }
- -
- - if (nmb->answers->rr_type == NMB_STATUS) {
- - DEBUG(3,("Name status "));
- - }
- + static time_t lasttime = 0;
- + time_t t = time(NULL);
-
- - if (nmb->answers->rr_type == NMB_QUERY) {
- - DEBUG(3,("Name query "));
- - }
- + int count = 0;
- + int name_refresh_time = NAME_POLL_REFRESH_TIME;
- + int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
- + if (max_count > 10) max_count = 10;
-
- - if (nmb->answers->rr_type == NMB_REG) {
- - DEBUG(3,("Name registration "));
- - }
- + name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
-
- - if (nmb->answers->rr_type == NMB_REL) {
- - DEBUG(3,("Name release "));
- - }
- + /* if (!lp_poll_wins()) return; polling of registered names allowed */
-
- - DEBUG(3,("response for %s from %s (bcast=%s)\n",
- - namestr(&nmb->answers->rr_name),
- - inet_ntoa(p->ip),
- - BOOLSTR(bcast)));
- -
- - if (!(n = find_name_query(nmb->header.name_trn_id))) {
- - DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
- - return;
- - }
- + if (!d) return;
-
- - n->num_msgs++; /* count number of responses received */
- + if (!lasttime) lasttime = t;
- + if (t - lasttime < NAME_POLL_INTERVAL) return;
-
- - switch (n->cmd_type)
- - {
- - case MASTER_SERVER_CHECK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
- - case SERVER_CHECK : DEBUG(4,("SERVER_CHECK\n")); break;
- - case FIND_MASTER : DEBUG(4,("FIND_MASTER\n")); break;
- - case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
- - case NAME_STATUS_CHECK : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
- - case CHECK_MASTER : DEBUG(4,("CHECK_MASTER\n")); break;
- - case NAME_CONFIRM_QUERY : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
- - default: break;
- - }
- - switch (n->cmd_type)
- - {
- - case MASTER_SERVER_CHECK:
- - case SERVER_CHECK:
- - case FIND_MASTER:
- - {
- - if (nmb->answers->rr_type == NMB_QUERY)
- - {
- - enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
- - NAME_STATUS_MASTER_CHECK :
- - NAME_STATUS_CHECK;
- - if (n->num_msgs > 1 && !strequal(qname,n->name.name))
- - {
- - /* one subnet, one master browser per workgroup */
- - /* XXXX force an election? */
- - DEBUG(1,("more than one master browser replied!\n"));
- - }
- -
- - /* initiate a name status check on the server that replied */
- - queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
- - nmb->answers->rr_name.name,
- - nmb->answers->rr_name.name_type,0,
- - False,False,n->to_ip);
- - }
- - else
- - {
- - DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- - }
- - break;
- - }
- -
- - case NAME_STATUS_MASTER_CHECK:
- - case NAME_STATUS_CHECK:
- - {
- - if (nmb->answers->rr_type == NMB_STATUS)
- - {
- - /* NMB_STATUS arrives: contains the workgroup name
- - and server name we require */
- - struct nmb_name name;
- - fstring serv_name;
- -
- - if (interpret_node_status(nmb->answers->rdata,
- - &name,0x1d,serv_name,p->ip))
- - {
- - if (*serv_name)
- - {
- - sync_server(n->cmd_type,serv_name,
- - name.name,name.name_type,
- - n->to_ip);
- - }
- - }
- - else
- - {
- - DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
- - }
- - }
- - else
- - {
- - DEBUG(1,("Name status reply has wrong answer rr_type\n"));
- - }
- - break;
- - }
- -
- - case CHECK_MASTER:
- - {
- - /* no action required here. it's when NO responses are received
- - that we need to do something (see expire_name_query_entries) */
- -
- - DEBUG(4, ("Master browser exists for %s at %s\n",
- - namestr(&n->name),
- - inet_ntoa(n->to_ip)));
- - if (n->num_msgs > 1)
- - {
- - DEBUG(1,("more than one master browser!\n"));
- - }
- - if (nmb->answers->rr_type != NMB_QUERY)
- - {
- - DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- - }
- - break;
- - }
- - case NAME_CONFIRM_QUERY:
- - {
- - DEBUG(4, ("Name query at WINS server: %s at %s - ",
- - namestr(&n->name),
- - inet_ntoa(n->to_ip)));
- - if (nmb->header.rcode == 0 && nmb->answers->rdata)
- - {
- - int nb_flags = nmb->answers->rdata[0];
- - struct in_addr found_ip;
- - putip((char*)&found_ip,&nmb->answers->rdata[2]);
- -
- - DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
- - add_netbios_entry(nmb->answers->rr_name.name,
- - nmb->answers->rr_name.name_type,
- - nb_flags,GET_TTL(0),STATUS_QUERY,found_ip,False);
- - }
- - else
- - {
- - DEBUG(4, (" NEGATIVE RESPONSE\n"));
- - }
- -
- - break;
- - }
- - default:
- - {
- - DEBUG(0,("unknown command received in response_netbios_packet\n"));
- - break;
- - }
- - }
- -}
- + lasttime = time(NULL);
-
- + for (n = d->namelist; n; n = n->next)
- + {
- + /* only do unique, registered names */
-
- -/****************************************************************************
- - process a nmb packet
- - ****************************************************************************/
- -void process_nmb(struct packet_struct *p)
- -{
- - struct nmb_packet *nmb = &p->packet.nmb;
- -
- - debug_nmb_packet(p);
- + if (n->source != REGISTER) continue;
- + if (!NAME_GROUP(n->nb_flags)) continue;
-
- - switch (nmb->header.opcode)
- - {
- - case 5:
- - case 8:
- - case 9:
- - {
- - if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
- - if (nmb->header.response)
- - response_name_reg(p);
- - else
- - reply_name_reg(p);
- - break;
- - }
- -
- - case 0:
- - {
- - if (nmb->header.response)
- - {
- - switch (nmb->question.question_type)
- - {
- - case 0x0:
- + if (n->refresh_time < t)
- {
- - response_netbios_packet(p);
- - break;
- + DEBUG(3,("Polling name %s\n", namestr(&n->name)));
- +
- + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
- + n->name.name, n->name.name_type,
- + 0,0,
- + False,False,n->ip,n->ip);
- + count++;
- }
- - }
- - return;
- - }
- - else if (nmb->header.qdcount>0)
- - {
- - switch (nmb->question.question_type)
- - {
- - case NMB_QUERY:
- - {
- - reply_name_query(p);
- - break;
- - }
- - case NMB_STATUS:
- +
- + if (count >= max_count)
- {
- - reply_name_status(p);
- - break;
- + /* don't do too many of these at once, but do enough to
- + cover everyone in the list */
- + return;
- }
- - }
- - return;
- - }
- - break;
- - }
- -
- - case 6:
- - {
- - if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- - {
- - DEBUG(2,("netbios release packet rejected\n"));
- - break;
- - }
- -
- - if (nmb->header.response)
- - response_name_release(p);
- - else
- - reply_name_release(p);
- - break;
- - }
- - }
- +
- + /* this name will be checked on again, if it's not removed */
- + n->refresh_time += name_refresh_time;
- + }
- }
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.doc samba-1.9.16alpha11/source/nameserv.doc
- --- samba-1.9.16alpha10/source/nameserv.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameserv.doc Thu Jul 11 04:48:28 1996
- @@ -0,0 +1,132 @@
- +this module deals with general maintenance of NetBIOS names.
- +
- +/*************************************************************************
- + query_refresh_names()
- + *************************************************************************/
- +
- +this function is responsible for polling all names registered in the
- +WINS database. it is planned to enable this function should samba
- +detect an inconsistency on the network, which could occur if the
- +samba NetBIOS daemon dies and is restarted.
- +
- +polling is done very infrequently, but all names will be covered
- +within a period NAME_POLL_REFRESH_TIME. a group of at most ten names
- +will be queried at once, at intervals of NAME_POLL_INTERVAL seconds.
- +if the total number of names queried in this way will take too long,
- +then the time that an individual name will next be polled is
- +increased accordingly.
- +
- +name query polling is functionality over-and-above the normal
- +requirement (see rfc1001.txt 15.1.7 point 7). it is normally the
- +responsibility of the owner of a name to re-register the name at
- +regular intervals.
- +
- +
- +/*************************************************************************
- + refresh_my_names()
- + *************************************************************************/
- +
- +this function is responsible for refreshing samba's names that have
- +been registered with other servers on a local subnet, or with another
- +WINS server if samba is using one.
- +
- +samba's names' refresh_time will be updated through the use of the function
- +add_my_name_entry().
- +
- +
- +/*************************************************************************
- + remove_my_names()
- + *************************************************************************/
- +
- +this function is responsible for removing all samba's SELF names. it
- +is used when samba receives a SIG_TERM. samba at present does not wait
- +for the WINS server to reply to the name releases sent out.
- +
- +
- +/*************************************************************************
- + add_my_names()
- + *************************************************************************/
- +
- +this function is responsible for adding and registering if necessary all
- +samba's SELF names, on each of its local subnets and with another WINS
- +server if samba is using one.
- +
- +/*************************************************************************
- + add_my_name_entry()
- + *************************************************************************/
- +
- +this function is responsible for registering or re-registering one of
- +samba's names, either on the local subnet or with another WINS server
- +if samba is using one.
- +
- +if the name is already in samba's database, then it is re-registered,
- +otherwise it is simply registered.
- +
- +if the name is being registered in a WINS capacity (the subnet to which
- +the name should be added is the WINS pseudo-subnet) then we add the entry
- +immediately if samba is a WINS server. it uses name_register_work()
- +because if the name is being added as part of becoming a master browser,
- +we want to carry on that process. if the name is registered with another
- +WINS server, we must wait for an answer from that WINS server. either
- +name_register_work() or name_unregister_work() will be called as a result.
- +
- +if the name is being registered on a local subnet, then it is
- +broadcast. an explicit rejection from another host will result
- +in name_unregister_work() being called. no response will, after
- +retrying, result in name_register_work() being called.
- +
- +what ever method is used, the name will either be registered
- +or rejected, and what ever process was taking place (becoming
- +a master browser for example) will carry on.
- +
- +expire_netbios_response_entries() is responsible for taking further
- +action if no response to the registration is received.
- +
- +note that there may be a large number of function calls on the
- +stack if become_master() is called and samba is configured as
- +a WINS server. the loop will be:
- +
- +become_master(), add_my_name_entry(), name_register_work() and
- +back to become_master() with the new value of the workgroup
- +'state'.
- +
- +
- +/*************************************************************************
- + remove_name_entry()
- + *************************************************************************/
- +
- +this function is responsible for removing a NetBIOS name. if the name
- +being removed is registered on a local subnet, a name release should be
- +broadcast on the local subnet.
- +
- +if the name is being released in a WINS capacity (the subnet to
- +which the name should be added is the WINS pseudo-subnet) then we
- +remove the entry immediately if samba is a WINS server. it uses
- +name_unregister_work() because if the name is being added as part of
- +becoming a master browser, we want to terminate that process. if the
- +name is released from another WINS server, we must wait for an
- +answer from that WINS server. name_unregister_work() will
- +definitely be called as a result, because at present we ignore
- +negative responses for a name release from a WINS server.
- +
- +if the name is being releasedd on a local subnet, then it is
- +broadcast. name_unregister_work() will definitely be called
- +because we ignore negative name releases at present.
- +
- +what ever method is used, the name will be released. (NOT TRUE!
- +see response_name_release())
- +
- +expire_netbios_response_entries() is responsible for taking further action
- +if no response to the name release is received.
- +
- +
- +/*************************************************************************
- + load_netbios_names()
- + *************************************************************************/
- +
- +this function is responsible for loading any NetBIOS names that samba,
- +in its WINS capacity, has written out to disk. all the relevant details
- +are recorded in this file, including the time-to-live. should the
- +time left to live be small, the name is not added back in to samba's
- +WINS database.
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.h samba-1.9.16alpha11/source/nameserv.h
- --- samba-1.9.16alpha10/source/nameserv.h Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/nameserv.h Thu Jul 18 20:53:15 1996
- @@ -20,18 +20,29 @@
-
- */
-
- +#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
- +
- /* NTAS uses 2, NT uses 1, WfWg uses 0 */
- #define MAINTAIN_LIST 2
- #define ELECTION_VERSION 1
-
- -#define MAX_DGRAM_SIZE (80*18+64)
- +#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */
- #define MIN_DGRAM_SIZE 12
-
- #define NMB_QUERY 0x20
- #define NMB_STATUS 0x21
- -#define NMB_REG 0x05
- -#define NMB_REL 0x06
-
- +#define NMB_REG 0x05 /* see rfc1002.txt 4.2.2,3,5,6,7,8 */
- +#define NMB_REG_REFRESH 0x09 /* see rfc1002.txt 4.2.4 */
- +#define NMB_REL 0x06 /* see rfc1002.txt 4.2.9,10,11 */
- +#define NMB_WAIT_ACK 0x07 /* see rfc1002.txt 4.2.16 */
- +/* XXXX what about all the other types?? 0x1, 0x2, 0x3, 0x4, 0x8? */
- +
- +#define FIND_SELF 0x01
- +#define FIND_WINS 0x02
- +#define FIND_LOCAL 0x04
- +
- +/* NetBIOS flags */
- #define NB_GROUP 0x80
- #define NB_PERM 0x02
- #define NB_ACTIVE 0x04
- @@ -44,7 +55,10 @@
- #define NB_FLGMSK 0x60
-
- #define REFRESH_TIME (15*60)
- +#define NAME_POLL_REFRESH_TIME (5*60)
- +#define NAME_POLL_INTERVAL 15
-
- +/* NetBIOS flag identifier */
- #define NAME_PERMANENT(p) ((p) & NB_PERM)
- #define NAME_ACTIVE(p) ((p) & NB_ACTIVE)
- #define NAME_CONFLICT(p) ((p) & NB_CONFL)
- @@ -56,23 +70,46 @@
- #define NAME_MFLAG(p) (((p) & NB_FLGMSK) == NB_MFLAG)
- #define NAME__FLAG(p) (((p) & NB_FLGMSK) == NB__FLAG)
-
- +/* server type identifiers */
- +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
- +#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
- +#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
- +
- +/* microsoft browser NetBIOS name */
- #define MSBROWSE "\001\002__MSBROWSE__\002"
-
- -enum name_search { FIND_SELF, FIND_GLOBAL };
- +/* mail slots */
- +#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
- +#define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON"
- +
- enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
- enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
- enum packet_type {NMB_PACKET, DGRAM_PACKET};
- -enum cmd_type
- +enum master_state
- {
- - NAME_STATUS_MASTER_CHECK,
- - NAME_STATUS_CHECK,
- - MASTER_SERVER_CHECK,
- - SERVER_CHECK,
- - FIND_MASTER,
- - CHECK_MASTER,
- + MST_NONE,
- + MST_WON,
- + MST_MSB,
- + MST_BROWSER,
- + MST_DOMAIN_NONE,
- + MST_DOMAIN_MEM,
- + MST_DOMAIN_TST,
- + MST_DOMAIN
- +};
- +
- +enum state_type
- +{
- + NAME_STATUS_PDC_SRV_CHK,
- + NAME_STATUS_SRV_CHK,
- + NAME_REGISTER_CHALLENGE,
- NAME_REGISTER,
- NAME_RELEASE,
- - NAME_CONFIRM_QUERY
- + NAME_QUERY_CONFIRM,
- + NAME_QUERY_SYNC,
- + NAME_QUERY_PDC_SRV_CHK,
- + NAME_QUERY_SRV_CHK,
- + NAME_QUERY_FIND_MST,
- + NAME_QUERY_MST_CHK
- };
-
- /* a netbios name structure */
- @@ -87,11 +124,15 @@
- {
- struct name_record *next;
- struct name_record *prev;
- - struct nmb_name name;
- - time_t death_time;
- - struct in_addr ip;
- - int nb_flags;
- - enum name_source source;
- +
- + struct nmb_name name; /* the netbios name */
- + struct in_addr ip; /* ip address of host that owns this name */
- + int nb_flags; /* netbios flags */
- +
- + enum name_source source; /* where the name came from */
- +
- + time_t death_time; /* time record must be removed (do not remove if 0) */
- + time_t refresh_time; /* time record should be refreshed */
- };
-
- /* browse and backup server cache for synchronising browse list */
- @@ -127,6 +168,9 @@
-
- struct server_record *serverlist;
-
- + /* stage of development from non-master to master browser / domain master */
- + enum master_state state;
- +
- /* work group info */
- fstring work_group;
- int token; /* used when communicating with backup browsers */
- @@ -137,6 +181,7 @@
- int announce_interval;
- BOOL needannounce;
-
- +
- /* election info */
- BOOL RunningElection;
- BOOL needelection;
- @@ -144,13 +189,64 @@
- uint32 ElectionCriterion;
- };
-
- -/* a subnet structure. it contains a list of workgroups */
- +/* initiated name queries recorded in this list to track any responses... */
- +struct response_record
- +{
- + struct response_record *next;
- + struct response_record *prev;
- +
- + uint16 response_id;
- + enum state_type state;
- +
- + int fd;
- + int quest_type;
- + struct nmb_name name;
- + int nb_flags;
- + time_t ttl;
- +
- + BOOL bcast;
- + BOOL recurse;
- + struct in_addr send_ip;
- + struct in_addr reply_to_ip;
- +
- + int num_msgs;
- +
- + time_t repeat_time;
- + time_t repeat_interval;
- + int repeat_count;
- +};
- +
- +/* a subnet structure. it contains a list of workgroups and netbios names*/
- +
- +/* note that a subnet of 255.255.255.255 contains all the WINS netbios names.
- + all communication from such nodes are on a non-broadcast basis: they
- + are point-to-point (P nodes) or mixed point-to-point and broadcast
- + (M nodes). M nodes use point-to-point as a preference, and will use
- + broadcasting for certain activities, or will resort to broadcasting as a
- + last resort, if the WINS server fails (users of wfwg will notice that their
- + machine often freezes for 30 seconds at a time intermittently, if the WINS
- + server is down).
- +
- + B nodes will have their own, totally separate subnet record, with their
- + own netbios name set. these do NOT interact with other subnet records'
- + netbios names, INCLUDING the WINS one (with an ip "address", so called,
- + of 255.255.255.255)
- +
- + there is a separate response list for each subnet record. in the case of
- + the 255.255.255.255 subnet record (WINS), the WINS server will be able to
- + use this to poll (infrequently!) each of its entries, to ensure that the
- + names are still in use.
- + XXXX this polling is a planned feature for a really over-cautious WINS server
- +*/
- +
- struct subnet_record
- {
- struct subnet_record *next;
- struct subnet_record *prev;
-
- - struct work_record *workgrouplist;
- + struct work_record *workgrouplist; /* list of workgroups */
- + struct name_record *namelist; /* list of netbios names */
- + struct response_record *responselist; /* list of responses expected */
-
- struct in_addr bcast_ip;
- struct in_addr mask_ip;
- @@ -202,25 +298,6 @@
- };
-
-
- -/* initiated name queries recorded in this list to track any responses... */
- -struct name_response_record
- -{
- - struct name_response_record *next;
- - struct name_response_record *prev;
- -
- - uint16 response_id;
- - enum cmd_type cmd_type;
- -
- - int fd;
- - struct nmb_name name;
- - BOOL bcast;
- - BOOL recurse;
- - struct in_addr to_ip;
- -
- - time_t start_time;
- - int num_msgs;
- -};
- -
- /* a datagram - this normally contains SMB data in the data[] array */
- struct dgram_packet {
- struct {
- @@ -258,11 +335,6 @@
- struct dgram_packet dgram;
- } packet;
- };
- -
- -
- -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
- -#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
- -#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
-
-
- /* ids for netbios packet types */
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservreply.c samba-1.9.16alpha11/source/nameservreply.c
- --- samba-1.9.16alpha10/source/nameservreply.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameservreply.c Thu Jul 18 20:53:16 1996
- @@ -0,0 +1,552 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Module name: nameservreply.c
- +
- + Revision History:
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 04 jul 96: lkcl@pires.co.uk
- + created module nameservreply containing NetBIOS reply functions
- +
- +*/
- +
- +#include "includes.h"
- +
- +extern int ClientNMB;
- +
- +extern int DEBUGLEVEL;
- +
- +extern struct in_addr ipgrp;
- +
- +
- +/****************************************************************************
- + add a netbios entry. respond to the (possibly new) owner.
- + **************************************************************************/
- +void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
- + uint16 response_id,
- + struct nmb_name *name,
- + int nb_flags, int ttl, struct in_addr register_ip,
- + BOOL new_owner, struct in_addr reply_to_ip)
- +{
- + /* register the old or the new owners' ip */
- + add_netbios_entry(d,name->name,name->name_type,
- + nb_flags,ttl,REGISTER,register_ip,False,True);
- +
- + /* reply yes or no to the host that requested the name */
- + send_name_response(fd,from_ip, response_id, NMB_REG,
- + new_owner, True,
- + name, nb_flags, ttl, reply_to_ip);
- +}
- +
- +/****************************************************************************
- +send a registration / release response: pos/neg
- +**************************************************************************/
- +void send_name_response(int fd, struct in_addr from_ip,
- + int name_trn_id, int opcode, BOOL success, BOOL recurse,
- + struct nmb_name *reply_name, int nb_flags, int ttl,
- + struct in_addr ip)
- +{
- + char rdata[6];
- + struct packet_struct p;
- +
- + int rcode = 0;
- +
- + if (success == False)
- + {
- + /* NEGATIVE RESPONSE */
- + rcode = 6;
- + }
- + else if (opcode == NMB_REG && recurse == False)
- + {
- + /* END-NODE CHALLENGE REGISTRATION RESPONSE */
- + rcode = 0;
- + }
- +
- + rdata[0] = nb_flags;
- + rdata[1] = 0;
- + putip(&rdata[2],(char *)&ip);
- +
- + p.ip = from_ip;
- + p.port = NMB_PORT;
- + p.fd = fd;
- + p.timestamp = time(NULL);
- + p.packet_type = NMB_PACKET;
- +
- + reply_netbios_packet(&p,name_trn_id,
- + rcode,opcode,opcode,recurse,
- + reply_name, 0x20, 0x1,
- + ttl,
- + rdata, 6);
- +}
- +
- +
- +/****************************************************************************
- +reply to a name release
- +****************************************************************************/
- +void reply_name_release(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + struct in_addr ip;
- + int nb_flags = nmb->additional->rdata[0];
- + BOOL bcast = nmb->header.nm_flags.bcast;
- + struct name_record *n;
- + struct subnet_record *d = NULL;
- + int search = 0;
- + BOOL success = False;
- +
- + putip((char *)&ip,&nmb->additional->rdata[2]);
- +
- + DEBUG(3,("Name release on name %s\n",
- + namestr(&nmb->question.question_name)));
- +
- + if (!(d = find_req_subnet(p->ip, bcast)))
- + {
- + DEBUG(3,("response packet: bcast %s not known\n",
- + inet_ntoa(p->ip)));
- + return;
- + }
- +
- + if (bcast)
- + search &= FIND_LOCAL;
- + else
- + search &= FIND_WINS;
- +
- + n = find_name_search(&d, &nmb->question.question_name,
- + search, ip);
- +
- + /* XXXX under what conditions should we reject the removal?? */
- + if (n && n->nb_flags == nb_flags)
- + {
- + success = True;
- +
- + remove_name(d,n);
- + n = NULL;
- + }
- +
- + if (bcast) return;
- +
- + /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
- + send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
- + success, False,
- + &nmb->question.question_name, nb_flags, 0, ip);
- +}
- +
- +
- +/****************************************************************************
- +reply to a reg request
- +**************************************************************************/
- +void reply_name_reg(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + struct nmb_name *question = &nmb->question.question_name;
- +
- + struct nmb_name *reply_name = question;
- +
- + char *qname = question->name;
- + int qname_type = question->name_type;
- +
- + BOOL bcast = nmb->header.nm_flags.bcast;
- +
- + int ttl = GET_TTL(nmb->additional->ttl);
- + int nb_flags = nmb->additional->rdata[0];
- + BOOL group = NAME_GROUP(nb_flags);
- +
- + struct subnet_record *d = NULL;
- + struct name_record *n = NULL;
- +
- + BOOL success = True;
- + BOOL secured_redirect = False;
- +
- + struct in_addr ip, from_ip;
- + int search = 0;
- +
- + putip((char *)&from_ip,&nmb->additional->rdata[2]);
- + ip = from_ip;
- +
- + DEBUG(3,("Name registration for name %s at %s\n",
- + namestr(question),inet_ntoa(ip)));
- +
- + if (group)
- + {
- + /* apparently we should return 255.255.255.255 for group queries
- + (email from MS) */
- + ip = ipgrp;
- + }
- +
- + if (!(d = find_req_subnet(p->ip, bcast)))
- + {
- + DEBUG(3,("response packet: bcast %s not known\n",
- + inet_ntoa(p->ip)));
- + return;
- + }
- +
- + if (bcast)
- + search &= FIND_LOCAL;
- + else
- + search &= FIND_WINS;
- +
- + /* see if the name already exists */
- + n = find_name_search(&d, question, search, from_ip);
- +
- + if (n)
- + {
- + if (!group) /* unique names */
- + {
- + if (n->source == SELF || NAME_GROUP(n->nb_flags))
- + {
- + /* no-one can register one of samba's names, nor can they
- + register a name that's a group name as a unique name */
- +
- + success = False;
- + }
- + else if(!ip_equal(ip, n->ip))
- + {
- + /* XXXX rfc1001.txt says:
- + * if we are doing secured WINS, we must send a Wait-Acknowledge
- + * packet (WACK) to the person who wants the name, then do a
- + * name query on the person who currently owns the unique name.
- + * if the current owner still says they own it, the person who wants
- + * the name can't have it. if they do not, or are not alive, they can.
- + */
- +
- + secured_redirect = True;
- +
- + reply_name = &n->name;
- + }
- + else
- + {
- + n->ip = ip;
- + n->death_time = ttl?p->timestamp+ttl*3:0;
- + DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
- + }
- + }
- + else
- + {
- + /* refresh the name */
- + if (n->source != SELF)
- + {
- + n->death_time = ttl?p->timestamp + ttl*3:0;
- + }
- + }
- +
- + /* XXXX bug reported by terryt@ren.pc.athabascau.ca */
- + /* names that people have checked for and not found get DNSFAILed.
- + we need to update the name record if someone then registers */
- +
- + if (n->source == DNSFAIL)
- + n->source = REGISTER;
- +
- + }
- + else
- + {
- + /* add the name to our name/subnet, or WINS, database */
- + n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
- + True,!bcast);
- + }
- +
- + /* if samba owns a unique name on a subnet, then it must respond and
- + disallow the attempted registration. if the registration is
- + successful by broadcast, only then is there no need to respond
- + (implicit registration: see rfc1001.txt 15.2.1).
- + */
- +
- + if (bcast && success) return;
- +
- + if (secured_redirect)
- + {
- + char rdata[2];
- +
- + /* XXXX luke is confused. RSVAL or SSVAL? assume NMB byte ordering */
- + RSSVAL(rdata,0,(nmb->header.opcode&0xf) + ((nb_flags&0xff) << 4));
- +
- + /* XXXX mistake in rfc1002.txt? 4.2.16: NULL is 0xa see 4.2.1.3
- + type = 0x0a; see rfc1002.txt 4.2.1.3
- + class = 0x01; see rfc1002.txt 4.2.16
- + */
- +
- + /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
- + reply_netbios_packet(p,nmb->header.name_trn_id,
- + 0,NMB_WAIT_ACK,NMB_WAIT_ACK,False,
- + reply_name, 0x0a, 0x01,
- + 15*1000, /* 15 seconds long enough to wait? */
- + rdata, 2);
- +
- + /* initiate some enquiries to the current owner. */
- + queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- + NAME_REGISTER_CHALLENGE,
- + reply_name->name,reply_name->name_type,nb_flags,0,
- + False, False, n->ip, p->ip);
- + }
- + else
- + {
- + /* Send a NAME REGISTRATION RESPONSE (pos/neg) see rfc1002.txt 4.2.13-14
- + or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
- + */
- +
- + send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG,
- + success, True,
- + reply_name, nb_flags, ttl, ip);
- + }
- +}
- +
- +
- +/****************************************************************************
- +reply to a name status query
- +****************************************************************************/
- +void reply_name_status(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *qname = nmb->question.question_name.name;
- + int ques_type = nmb->question.question_name.name_type;
- + char rdata[MAX_DGRAM_SIZE];
- + char *countptr, *buf, *bufend;
- + int names_added;
- + struct name_record *n;
- + struct subnet_record *d = NULL;
- + int search = FIND_SELF;
- +
- + BOOL bcast = nmb->header.nm_flags.bcast;
- +
- + if (!(d = find_req_subnet(p->ip, bcast)))
- + {
- + DEBUG(3,("Name status req: bcast %s not known\n",
- + inet_ntoa(p->ip)));
- + return;
- + }
- +
- + DEBUG(3,("Name status for name %s %s\n",
- + namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
- +
- + if (bcast)
- + search |= FIND_WINS;
- + else
- + search |= FIND_LOCAL;
- +
- + n = find_name_search(&d, &nmb->question.question_name,
- + search, p->ip);
- +
- + if (!n) return;
- +
- + /* XXXX hack, we should calculate exactly how many will fit */
- + bufend = &rdata[MAX_DGRAM_SIZE] - 18;
- + countptr = buf = rdata;
- + buf += 1;
- +
- + names_added = 0;
- +
- + for (n = d->namelist ; n && buf < bufend; n = n->next)
- + {
- + int name_type = n->name.name_type;
- +
- + if (n->source != SELF) continue;
- +
- + /* start with first bit of putting info in buffer: the name */
- +
- + bzero(buf,18);
- + sprintf(buf,"%-15.15s",n->name.name);
- + strupper(buf);
- +
- + /* now check if we want to exclude other workgroup names
- + from the response. if we don't exclude them, windows clients
- + get confused and will respond with an error for NET VIEW */
- +
- + if (name_type >= 0x1b && name_type <= 0x20 &&
- + ques_type >= 0x1b && ques_type <= 0x20)
- + {
- + if (!strequal(qname, n->name.name)) continue;
- + }
- +
- + /* carry on putting name info in buffer */
- +
- + buf[15] = name_type;
- + buf[16] = n->nb_flags;
- +
- + buf += 18;
- +
- + names_added++;
- + }
- +
- + SCVAL(countptr,0,names_added);
- +
- + /* XXXXXXX we should fill in more fields of the statistics structure */
- + bzero(buf,64);
- + {
- + extern int num_good_sends,num_good_receives;
- + SIVAL(buf,20,num_good_sends);
- + SIVAL(buf,24,num_good_receives);
- + }
- +
- + SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
- +
- + buf += 64;
- +
- + /* Send a POSITIVE NAME STATUS RESPONSE */
- + reply_netbios_packet(p,nmb->header.name_trn_id,
- + 0,NMB_STATUS,0,True,
- + &nmb->question.question_name,
- + nmb->question.question_type,
- + nmb->question.question_class,
- + 0,
- + rdata,PTR_DIFF(buf,rdata));
- +}
- +
- +
- +/***************************************************************************
- +reply to a name query.
- +
- +with broadcast name queries:
- +
- + - only reply if the query is for one of YOUR names. all other machines on
- + the network will be doing the same thing (that is, only replying to a
- + broadcast query if they own it)
- + NOTE: broadcast name queries should only be sent out by a machine
- + if they HAVEN'T been configured to use WINS. this is generally bad news
- + in a wide area tcp/ip network and should be rectified by the systems
- + administrator. USE WINS! :-)
- + - the exception to this is if the query is for a Primary Domain Controller
- + type name (0x1b), in which case, a reply is sent.
- +
- + - NEVER send a negative response to a broadcast query. no-one else will!
- +
- +with directed name queries:
- +
- + - if you are the WINS server, you are expected to respond with either
- + a negative response, a positive response, or a wait-for-acknowledgement
- + packet, and then later on a pos/neg response.
- +
- +****************************************************************************/
- +void reply_name_query(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + struct nmb_name *question = &nmb->question.question_name;
- + int name_type = question->name_type;
- + BOOL bcast = nmb->header.nm_flags.bcast;
- + int ttl=0;
- + int rcode = 0;
- + int nb_flags = 0;
- + struct in_addr retip;
- + char rdata[6];
- + struct subnet_record *d = NULL;
- + BOOL success = True;
- + struct name_record *n;
- +
- + /* directed queries are for WINS server: broadcasts are local SELF queries.
- + the exception is PDC names. */
- +
- + int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
- +
- + if (name_type == 0x1b)
- + {
- + /* even if it's a broadcast, we don't ignore queries for PDC names */
- + search = FIND_WINS;
- + }
- +
- + if (search | FIND_LOCAL)
- + {
- + if (!(d = find_req_subnet(p->ip, bcast)))
- + {
- + DEBUG(3,("name query: bcast %s not known\n",
- + inet_ntoa(p->ip)));
- + success = False;
- + }
- + }
- + else
- + {
- + if (!(d = find_subnet(ipgrp)))
- + {
- + DEBUG(3,("name query: wins search %s not known\n",
- + inet_ntoa(p->ip)));
- + success = False;
- + }
- + }
- +
- + DEBUG(3,("Name query "));
- +
- + if (search == 0)
- + {
- + /* eh? no criterion for searching database. help! */
- + success = False;
- + }
- +
- + if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
- + {
- + /* don't respond to broadcast queries unless the query is for
- + a name we own or it is for a Primary Domain Controller name */
- +
- + if (bcast && n->source != SELF && name_type != 0x1b) {
- + if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
- + /* never reply with a negative response to broadcast queries */
- + return;
- + }
- + }
- +
- + /* name is directed query, or it's self, or it's a PDC type name, or
- + we're replying on behalf of a caller because they are on a different
- + subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
- + switched off in environments where broadcasts are forwarded */
- +
- + /* XXXX note: for proxy servers, we should forward the query on to
- + another WINS server if the name is not in our database, or we are
- + not a WINS server ourselves
- + */
- + ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0);
- + retip = n->ip;
- + nb_flags = n->nb_flags;
- + }
- + else
- + {
- + if (bcast) return; /* never reply negative response to bcasts */
- + success = False;
- + }
- +
- + /* if the IP is 0 then substitute my IP */
- + if (zero_ip(retip)) retip = *iface_ip(p->ip);
- +
- + if (success)
- + {
- + rcode = 0;
- + DEBUG(3,("OK %s\n",inet_ntoa(retip)));
- + }
- + else
- + {
- + rcode = 3;
- + DEBUG(3,("UNKNOWN\n"));
- + }
- +
- + if (success)
- + {
- + rdata[0] = nb_flags;
- + rdata[1] = 0;
- + putip(&rdata[2],(char *)&retip);
- + }
- +
- + reply_netbios_packet(p,nmb->header.name_trn_id,
- + rcode,NMB_QUERY,0,True,
- + &nmb->question.question_name,
- + nmb->question.question_type,
- + nmb->question.question_class,
- + ttl,
- + rdata, success ? 6 : 0);
- +}
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservreply.doc samba-1.9.16alpha11/source/nameservreply.doc
- --- samba-1.9.16alpha10/source/nameservreply.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameservreply.doc Thu Jul 11 04:48:28 1996
- @@ -0,0 +1,186 @@
- +/*************************************************************************
- + reply_name_query()
- + *************************************************************************/
- +
- +this function is responsible for replying to a NetBIOS name query.
- +
- +there are two kinds of name queries: directed, and broadcast. directed
- +queries are usually sent to samba in its WINS capacity. such hosts are
- +termed 'point-to-point' hosts. broadcast queries are usually sent from
- +'broadcast' or 'mixed' hosts.
- +
- +broadcasting is used by either older NetBIOS hosts, new NetBIOS hosts that
- +have not had WINS capabilities added and new NetBIOS hosts that think the
- +WINS server has died.
- +
- +the samba NetBIOS name database is divided into sections, on a
- +per-subnet basis. there is also a WINS NetBIOS name database, and for
- +convenience this is added as a pseudo-subnet with the ip address of
- +255.255.255.255.
- +
- +the local subnet NetBIOS name databases only contain samba's names.
- +the reason for this is that if a broadcast query is received, a NetBIOS
- +hosts is only expected to respond if that query is for one of its own
- +names (the exception to this is if a host is configured as a 'proxy'
- +server, in which case, samba should redirect the query to another WINS
- +server).
- +
- +the WINS pseudo-subnet NetBIOS database contains all NetBIOS names
- +that are not 'special browser' type names (regarding this i am a
- +_bit_ confused :-). names of type 0x01, 0x1d and 0x1e i consider to
- +be 'special browser' names. at the moment. maybe.
- +
- +the type of search to be initiated is determined. if the NetBIOS name
- +type is a non-special-browser name, then the WINS database is included
- +in the search.
- +
- +if the name is not a special browser name, then we need to find the
- +right subnet that the query came from. this is done using
- +find_req_subnet(). this also has the benefit of stopping any queries
- +from subnets that samba does not know about.
- +
- +if the query is a broadcast query, then the database of the local subnet
- +is included in the search.
- +
- +the name is then searched for in the appropriate NetBIOS data structures.
- +if it is found, then we need to check whether it is appropriate for us
- +to reply to such a query.
- +
- +we will only reply if the query is a directed query, the name belongs to
- +samba on that subnet, or the name is a primary domain controller type,
- +or we're doing replies on behalf of hosts on subnets not known to the
- +host issuing the query. in the latter instance, it would be appropriate
- +if samba is using a WINS server for it to forward the name query on to
- +this WINS server.
- +
- +reply_name_query() then takes note of all the information that is
- +needed to construct a reply to the caller. a negative reply (if the
- +name is unknown to samba) or a positive reply (the name is known to
- +samba) is then issued.
- +
- +
- +/*************************************************************************
- + reply_name_status()
- + *************************************************************************/
- +
- +this function is responsible for constructing a reply to a NetBIOS
- +name status query. this response contains all samba's NetBIOS names
- +on the subnet that the query came in from.
- +
- +a reply will only be made if the NetBIOS name being queried exists.
- +
- +see rfc1001.txt and rfc1002.txt for details of the name status reply.
- +
- +
- +/*************************************************************************
- + reply_name_reg()
- + *************************************************************************/
- +
- +this function is responsible for updating the NetBIOS name database
- +from registration packets sent out by hosts wishing to register a
- +name, and for informing them, if necessary, if this is acceptable
- +or not.
- +
- +name registration can be done by broadcast or by point-to-point,
- +i.e the registration is sent directly to samba in its capacity as
- +a WINS server.
- +
- +if the name registration is done by broadcast (see rfc1001.txt 15.2.1),
- +then samba's involvement in replying is limited to whether that name
- +is owned by samba or not, on the relevant subnet.
- +
- +if the name registration is done point-to-point (see rfc1001.txt 15.2.2)
- +then samba will first need to check its WINS name database records and
- +proceed accordingly.
- +
- +samba looks for the appropriate subnet record that the registration
- +should be added to / checked against, using find_req_subnet().
- +
- +next, the name is searched for in the local database or the WINS
- +database as appropriate.
- +
- +if the name is not found, then it is added to the NetBIOS name database,
- +using add_netbios_entry(), which may choose not to add the name (not
- +that this affects the registration of the name on the network in any way).
- +it will only add names to the WINS database, and even then it will only
- +add non-special-browser type names.
- +
- +if the name is found, then samba must decide whether to accept the name
- +or not. a group name is always added. for unique names, further checks
- +need to be carried out.
- +
- +firstly, if the name in the database is one of samba's names, or if the
- +name in the database is a group name, then it cannot be added as a unique
- +name belonging to someone else. it is therefore rejected.
- +
- +secondly, if the ip address of the name being registered does not match
- +against the ip in the database, then the unique name may belong to
- +someone else. a check needs to be carried out with the owner in case
- +they still wish to keep this name. a detailed discussion of what action
- +to take is in rfc1001.txt 15.2.2.2 and 15.2.2.3.
- +
- +samba currently implements non-secured WINS, whereupon the responsibility
- +for checking the name is passed on to the host doing the registration.
- +rfc1001.txt refers to this as an END-NODE CHALLENGE REGISTRATION RESPONSE.
- +(samba itself cannot yet cope with receiving such responses if it
- +registers its names with another WINS server).
- +
- +having decided what kind of response to send (if any - acceptance of
- +name registrations by broadcast is implicit), samba will send either a
- +positive or negative NAME REGISTRATION RESPONSE, or an END-NODE CHALLENGE
- +REGISTRATION RESPONSE to the host that initially sent the registration.
- +
- +whew.
- +
- +
- +/*************************************************************************
- + reply_name_release()
- + *************************************************************************/
- +
- +this function is responsible for removing a NetBIOS name from the
- +database when a server sends a release packet.
- +
- +samba looks for the appropriate subnet record that the release should
- +be removed from, using find_req_subnet(). next, the name is searched
- +for in the local database or the WINS database as appropriate.
- +
- +if the name is found, it is removed from the database and a
- +positive reply is sent confirming this. if the name is not
- +found, a negative reply is sent.
- +
- +a reply is _not_ sent if the release was done by broadcast: the
- +release is implicit, and we should be grateful that they bothered
- +to tell us. if the release was done by directed packet, then
- +we deal with it as a WINS server and must reply (pos / neg).
- +
- +at present, the criteria for removing a name have yet to be
- +developed / experimented with. at present, the only flags that
- +are checked are the NetBIOS flags.
- +
- +
- +/*************************************************************************
- + send_name_response()
- + *************************************************************************/
- +
- +this function is a wrap around reply_netbios_packet(). it sends
- +a response to a name registration or release packet, minimising
- +the function parameters needed to do this.
- +
- +if the function is called with the parameter 'success' set to
- +True, then a positive response (to the registration or release)
- +is made (see rfc1002.txt 4.2.5 and 4.2.10). if this parameter
- +is False, then a negative response is issued (see rfc1002.txt
- +4.2.6 and 4.2.11)
- +
- +if the function is called with a registration code, and the
- +parameter 'recurse' is False, then an End-Node Challenge
- +Registration response is issued (see rfc1002.txt 4.2.7)
- +
- +note: this function could also easily be used for name conflict
- +demand (see rfc1002.txt 4.2.8).
- +
- +note: End-Node Challenge Registration response is only sent in
- +non-secured NetBIOS Name Server implementations. samba now
- +implements secured NetBIOS Name Server functionality (see
- +rfc1001.txt 15.1.6).
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservresp.c samba-1.9.16alpha11/source/nameservresp.c
- --- samba-1.9.16alpha10/source/nameservresp.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameservresp.c Thu Jul 18 20:53:16 1996
- @@ -0,0 +1,743 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1996
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- + Revision History:
- +
- + Module name: nameservresp.c
- +
- + 14 jan 96: lkcl@pires.co.uk
- + added multiple workgroup domain master support
- +
- + 05 jul 96: lkcl@pires.co.uk
- + created module nameservresp containing NetBIOS response functions
- +
- +*/
- +
- +#include "includes.h"
- +
- +extern int ClientNMB;
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring scope;
- +extern struct in_addr ipzero;
- +
- +#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
- +
- +
- +/****************************************************************************
- + response for a reg release received. samba has asked a WINS server if it
- + could release a name.
- + **************************************************************************/
- +static void response_name_release(struct subnet_record *d,
- + struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *name = nmb->question.question_name.name;
- + int type = nmb->question.question_name.name_type;
- +
- + DEBUG(4,("response name release received\n"));
- +
- + if (nmb->header.rcode == 0 && nmb->answers->rdata)
- + {
- + /* IMPORTANT: see expire_netbios_response_entries() */
- +
- + struct in_addr found_ip;
- + putip((char*)&found_ip,&nmb->answers->rdata[2]);
- +
- + /* NOTE: we only release our own names at present */
- + if (ismyip(found_ip))
- + {
- + name_unregister_work(d,name,type);
- + }
- + else
- + {
- + DEBUG(2,("name release for different ip! %s %s\n",
- + inet_ntoa(found_ip),
- + namestr(&nmb->question.question_name)));
- + }
- + }
- + else
- + {
- + DEBUG(2,("name release for %s rejected!\n",
- + namestr(&nmb->question.question_name)));
- +
- + /* XXXX PANIC! what to do if it's one of samba's own names? */
- +
- + /* XXXX do we honestly care if our name release was rejected?
- + only if samba is issuing the release on behalf of some out-of-sync
- + server. if it's one of samba's SELF names, we don't care. */
- + }
- +}
- +
- +
- +/****************************************************************************
- +response for a reg request received
- +**************************************************************************/
- +static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *name = nmb->question.question_name.name;
- + int type = nmb->question.question_name.name_type;
- + BOOL bcast = nmb->header.nm_flags.bcast;
- +
- + DEBUG(4,("response name registration received!\n"));
- +
- + if (nmb->header.rcode == 0 && nmb->answers->rdata)
- + {
- + /* IMPORTANT: see expire_netbios_response_entries() */
- +
- + int nb_flags = nmb->answers->rdata[0];
- + int ttl = nmb->answers->ttl;
- + struct in_addr found_ip;
- +
- + putip((char*)&found_ip,&nmb->answers->rdata[2]);
- +
- + name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
- + }
- + else
- + {
- + DEBUG(1,("name registration for %s rejected!\n",
- + namestr(&nmb->question.question_name)));
- +
- + /* oh dear. we have problems. possibly unbecome a master browser. */
- + name_unregister_work(d,name,type);
- + }
- +}
- +
- +
- +/****************************************************************************
- + response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
- + NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
- + ****************************************************************************/
- +static void response_server_check(struct nmb_name *ans_name,
- + struct response_record *n, struct subnet_record *d)
- +{
- + /* issue another state: this time to do a name status check */
- +
- + enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
- + NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
- +
- + /* initiate a name status check on the server that replied */
- + queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
- + ans_name->name, ans_name->name_type,
- + 0,0,
- + False,False,n->send_ip,n->reply_to_ip);
- +}
- +
- +
- +/****************************************************************************
- + interpret a node status response. this is pretty hacked: we need two bits of
- + info. a) the name of the workgroup b) the name of the server. it will also
- + add all the names it finds into the namelist.
- +****************************************************************************/
- +static BOOL interpret_node_status(struct subnet_record *d,
- + char *p, struct nmb_name *name,int t,
- + char *serv_name, struct in_addr ip, BOOL bcast)
- +{
- + int level = t==0x20 ? 4 : 0;
- + int numnames = CVAL(p,0);
- + BOOL found = False;
- +
- + DEBUG(level,("received %d names\n",numnames));
- +
- + p += 1;
- +
- + if (serv_name) *serv_name = 0;
- +
- + while (numnames--)
- + {
- + char qname[17];
- + int type;
- + fstring flags;
- + int nb_flags;
- +
- + BOOL group = False;
- + BOOL add = False;
- +
- + *flags = 0;
- +
- + StrnCpy(qname,p,15);
- + type = CVAL(p,15);
- + nb_flags = p[16];
- + trim_string(qname,NULL," ");
- +
- + p += 18;
- +
- + if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
- + if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
- + if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
- + if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
- + if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
- + if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
- + if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
- + if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
- + if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
- +
- + /* might as well update our namelist while we're at it */
- + if (add)
- + {
- + struct in_addr nameip;
- + enum name_source src;
- +
- + if (ismyip(ip)) {
- + nameip = ipzero;
- + src = SELF;
- + } else {
- + nameip = ip;
- + src = STATUS_QUERY;
- + }
- + add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
- + }
- +
- + /* we want the server name */
- + if (serv_name && !*serv_name && !group && t == 0)
- + {
- + StrnCpy(serv_name,qname,15);
- + serv_name[15] = 0;
- + }
- +
- + /* looking for a name and type? */
- + if (name && !found && (t == type))
- + {
- + /* take a guess at some of the name types we're going to ask for.
- + evaluate whether they are group names or no... */
- + if (((t == 0x1b || t == 0x1d ) && !group) ||
- + ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
- + {
- + found = True;
- + make_nmb_name(name,qname,type,scope);
- + }
- + }
- +
- + DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
- + }
- + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
- + IVAL(p,20),IVAL(p,24)));
- + return found;
- +}
- +
- +
- +/****************************************************************************
- + response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
- + and NAME_STATUS_SRV_CHK dealt with here.
- + ****************************************************************************/
- +static void response_name_status_check(struct in_addr ip,
- + struct nmb_packet *nmb, BOOL bcast,
- + struct response_record *n, struct subnet_record *d)
- +{
- + /* NMB_STATUS arrives: contains workgroup name and server name required.
- + amongst other things. */
- +
- + struct nmb_name name;
- + fstring serv_name;
- +
- + if (interpret_node_status(d,nmb->answers->rdata,
- + &name,name.name_type,serv_name,ip,bcast))
- + {
- + if (*serv_name)
- + {
- + sync_server(n->state,serv_name,
- + name.name,name.name_type, n->send_ip);
- + }
- + }
- + else
- + {
- + DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
- + }
- +}
- +
- +
- +/****************************************************************************
- + response from a name query for secured WINS registration. a state of
- + NAME_REGISTER_CHALLENGE is dealt with here.
- + ****************************************************************************/
- +static void response_name_query_register(struct nmb_packet *nmb,
- + struct nmb_name *ans_name,
- + struct response_record *n, struct subnet_record *d)
- +{
- + struct in_addr register_ip;
- + BOOL new_owner;
- +
- + DEBUG(4, ("Name query at %s ip %s - ",
- + namestr(&n->name), inet_ntoa(n->send_ip)));
- +
- + if (!name_equal(&n->name, ans_name))
- + {
- + /* someone gave us the wrong name as a reply. oops. */
- + /* XXXX should say to them 'oi! release that name!' */
- +
- + DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
- + return;
- + }
- +
- + if (nmb->header.rcode == 0 && nmb->answers->rdata)
- + {
- + /* we had sent out a name query to the current owner
- + of a name because someone else wanted it. now they
- + have responded saying that they still want the name,
- + so the other host can't have it.
- + */
- +
- + /* first check all the details are correct */
- +
- + int nb_flags = nmb->answers->rdata[0];
- + struct in_addr found_ip;
- +
- + putip((char*)&found_ip,&nmb->answers->rdata[2]);
- +
- + if (nb_flags != n->nb_flags)
- + {
- + /* someone gave us the wrong nb_flags as a reply. oops. */
- + /* XXXX should say to them 'oi! release that name!' */
- +
- + DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
- + DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
- + return;
- + }
- +
- + if (!ip_equal(n->send_ip, found_ip))
- + {
- + /* someone gave us the wrong ip as a reply. oops. */
- + /* XXXX should say to them 'oi! release that name!' */
- +
- + DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
- + DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
- + return;
- + }
- +
- + DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
- +
- + /* fine: now tell the other host they can't have the name */
- + register_ip = n->send_ip;
- + new_owner = False;
- + }
- + else
- + {
- + DEBUG(4, (" NEGATIVE RESPONSE!\n"));
- +
- + /* the owner didn't want the name: the other host can have it */
- + register_ip = n->reply_to_ip;
- + new_owner = True;
- + }
- +
- + /* register the old or the new owners' ip */
- + add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
- + GET_TTL(0), register_ip,
- + new_owner, n->reply_to_ip);
- +}
- +
- +
- +/****************************************************************************
- + response from a name query to sync browse lists or to update our netbios
- + entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
- + ****************************************************************************/
- +static void response_name_query_sync(struct nmb_packet *nmb,
- + struct nmb_name *ans_name, BOOL bcast,
- + struct response_record *n, struct subnet_record *d)
- +{
- + DEBUG(4, ("Name query at %s ip %s - ",
- + namestr(&n->name), inet_ntoa(n->send_ip)));
- +
- + if (!name_equal(&n->name, ans_name))
- + {
- + /* someone gave us the wrong name as a reply. oops. */
- + DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
- + return;
- + }
- +
- + if (nmb->header.rcode == 0 && nmb->answers->rdata)
- + {
- + int nb_flags = nmb->answers->rdata[0];
- + struct in_addr found_ip;
- +
- + putip((char*)&found_ip,&nmb->answers->rdata[2]);
- +
- + if (!ip_equal(n->send_ip, found_ip))
- + {
- + /* someone gave us the wrong ip as a reply. oops. */
- + DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
- + DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
- + return;
- + }
- +
- + DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
- +
- + if (n->state == NAME_QUERY_SYNC)
- + {
- + struct work_record *work = NULL;
- + if ((work = find_workgroupstruct(d, ans_name->name, False)))
- + {
- + /* the server is there: sync quick before it (possibly) dies! */
- + sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
- + found_ip);
- + }
- + }
- + else
- + {
- + /* update our netbios name list (re-register it if necessary) */
- + add_netbios_entry(d, ans_name->name, ans_name->name_type,
- + nb_flags,GET_TTL(0),REGISTER,
- + found_ip,False,!bcast);
- + }
- + }
- + else
- + {
- + DEBUG(4, (" NEGATIVE RESPONSE!\n"));
- +
- + if (n->state == NAME_QUERY_CONFIRM)
- + {
- + /* XXXX remove_netbios_entry()? */
- + /* lots of things we ought to do, here. if we get here,
- + then we're in a mess: our name database doesn't match
- + reality. sort it out
- + */
- + remove_netbios_name(d,n->name.name, n->name.name_type,
- + REGISTER,n->send_ip);
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- + report the response record type
- + ****************************************************************************/
- +static void debug_rr_type(int rr_type)
- +{
- + switch (rr_type)
- + {
- + case NMB_STATUS: DEBUG(3,("Name status ")); break;
- + case NMB_QUERY : DEBUG(3,("Name query ")); break;
- + case NMB_REG : DEBUG(3,("Name registration ")); break;
- + case NMB_REL : DEBUG(3,("Name release ")); break;
- + default : DEBUG(1,("wrong response packet type received")); break;
- + }
- +}
- +
- +/****************************************************************************
- + report the response record nmbd state
- + ****************************************************************************/
- +void debug_state_type(int state)
- +{
- + /* report the state type to help debugging */
- + switch (state)
- + {
- + case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
- + case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
- + case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
- + case NAME_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
- + case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
- + case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
- + case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
- + case NAME_REGISTER_CHALLENGE: DEBUG(4,("NAME_REGISTER_CHALLENGE\n")); break;
- + case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
- + case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
- + case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
- + default: break;
- + }
- +}
- +
- +/****************************************************************************
- + report any problems with the fact that a response has been received.
- +
- + (responses for certain types of operations are only expected from one host)
- + ****************************************************************************/
- +static BOOL response_problem_check(struct response_record *n,
- + struct nmb_packet *nmb, char *qname)
- +{
- + switch (nmb->answers->rr_type)
- + {
- + case NMB_REL:
- + {
- + if (n->num_msgs > 1)
- + {
- + DEBUG(1,("more than one release name response received!\n"));
- + return True;
- + }
- + break;
- + }
- +
- + case NMB_REG:
- + {
- + if (n->num_msgs > 1)
- + {
- + DEBUG(1,("more than one register name response received!\n"));
- + return True;
- + }
- + break;
- + }
- +
- + case NMB_QUERY:
- + {
- + if (n->num_msgs > 1)
- + {
- + if (nmb->header.rcode == 0 && nmb->answers->rdata)
- + {
- + int nb_flags = nmb->answers->rdata[0];
- +
- + if ((!NAME_GROUP(nb_flags)))
- + {
- + /* oh dear. more than one person responded to a unique name.
- + there is either a network problem, a configuration problem
- + or a server is mis-behaving */
- +
- + /* XXXX mark the name as in conflict, and then let the
- + person who just responded know that they must also mark it
- + as in conflict, and therefore must NOT use it.
- + see rfc1001.txt 15.1.3.5 */
- +
- + /* this may cause problems for some early versions of nmbd */
- +
- + switch (n->state)
- + {
- + case NAME_QUERY_FIND_MST:
- + {
- + /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
- + return False;
- + }
- + case NAME_QUERY_PDC_SRV_CHK:
- + case NAME_QUERY_SRV_CHK:
- + case NAME_QUERY_MST_CHK:
- + {
- + if (!strequal(qname,n->name.name))
- + {
- + /* one subnet, one master browser per workgroup */
- + /* XXXX force an election? */
- +
- + DEBUG(3,("more than one master browser replied!\n"));
- + return True;
- + }
- + break;
- + }
- + default: break;
- + }
- + DEBUG(3,("Unique Name conflict detected!\n"));
- + return True;
- + }
- + }
- + else
- + {
- + /* we have received a negative reply, having already received
- + at least one response (pos/neg). something's really wrong! */
- +
- + DEBUG(3,("wierd name query problem detected!\n"));
- + return True;
- + }
- + }
- + }
- + }
- + return False;
- +}
- +
- +/****************************************************************************
- + check that the response received is compatible with the response record
- + ****************************************************************************/
- +static BOOL response_compatible(struct response_record *n,
- + struct nmb_packet *nmb)
- +{
- + switch (n->state)
- + {
- + case NAME_RELEASE:
- + {
- + if (nmb->answers->rr_type != NMB_REL)
- + {
- + DEBUG(1,("Name release reply has wrong answer rr_type\n"));
- + return False;
- + }
- + break;
- + }
- +
- + case NAME_REGISTER:
- + {
- + if (nmb->answers->rr_type != NMB_REG)
- + {
- + DEBUG(1,("Name register reply has wrong answer rr_type\n"));
- + return False;
- + }
- + break;
- + }
- +
- + case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
- + case NAME_QUERY_CONFIRM:
- + case NAME_QUERY_SYNC:
- + case NAME_QUERY_PDC_SRV_CHK:
- + case NAME_QUERY_SRV_CHK:
- + case NAME_QUERY_FIND_MST:
- + case NAME_QUERY_MST_CHK:
- + {
- + if (nmb->answers->rr_type != NMB_QUERY)
- + {
- + DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- + return False;
- + }
- + break;
- + }
- +
- + case NAME_STATUS_PDC_SRV_CHK:
- + case NAME_STATUS_SRV_CHK:
- + {
- + if (nmb->answers->rr_type != NMB_STATUS)
- + {
- + DEBUG(1,("Name status reply has wrong answer rr_type\n"));
- + return False;
- + }
- + break;
- + }
- +
- + default:
- + {
- + DEBUG(1,("unknown state type received in response_netbios_packet\n"));
- + return False;
- + }
- + }
- + return True;
- +}
- +
- +
- +/****************************************************************************
- + process the response packet received
- + ****************************************************************************/
- +static void response_process(struct subnet_record *d, struct packet_struct *p,
- + struct response_record *n, struct nmb_packet *nmb,
- + BOOL bcast, struct nmb_name *ans_name)
- +{
- + switch (n->state)
- + {
- + case NAME_RELEASE:
- + {
- + response_name_release(d, p);
- + break;
- + }
- +
- + case NAME_REGISTER:
- + {
- + response_name_reg(d, p);
- + break;
- + }
- +
- + case NAME_REGISTER_CHALLENGE:
- + {
- + response_name_query_register(nmb, ans_name, n, d);
- + break;
- + }
- +
- + case NAME_QUERY_PDC_SRV_CHK:
- + case NAME_QUERY_SRV_CHK:
- + case NAME_QUERY_FIND_MST:
- + {
- + response_server_check(ans_name, n, d);
- + break;
- + }
- +
- + case NAME_STATUS_PDC_SRV_CHK:
- + case NAME_STATUS_SRV_CHK:
- + {
- + response_name_status_check(p->ip, nmb, bcast, n, d);
- + break;
- + }
- +
- + case NAME_QUERY_CONFIRM:
- + case NAME_QUERY_SYNC:
- + {
- + response_name_query_sync(nmb, ans_name, bcast, n, d);
- + break;
- + }
- + case NAME_QUERY_MST_CHK:
- + {
- + /* no action required here. it's when NO responses are received
- + that we need to do something. see expire_name_query_entries() */
- +
- + DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
- + namestr(&n->name), inet_ntoa(n->send_ip)));
- + break;
- + }
- +
- + default:
- + {
- + DEBUG(1,("unknown state type received in response_netbios_packet\n"));
- + break;
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- + response from a netbios packet.
- + ****************************************************************************/
- +void response_netbios_packet(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + struct nmb_name *question = &nmb->question.question_name;
- + struct nmb_name *ans_name = NULL;
- + char *qname = question->name;
- + BOOL bcast = nmb->header.nm_flags.bcast;
- + struct response_record *n;
- + struct subnet_record *d = NULL;
- +
- + if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
- + DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
- + return;
- + }
- +
- + if (!d)
- + {
- + DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
- + return;
- + }
- +
- + if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
- + {
- + DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
- + DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
- + return;
- + }
- +
- + if (nmb->answers == NULL)
- + {
- + /* hm. the packet received was a response, but with no answer. wierd! */
- + DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
- + inet_ntoa(p->ip), BOOLSTR(bcast)));
- + return;
- + }
- +
- + ans_name = &nmb->answers->rr_name;
- + DEBUG(3,("response for %s from %s (bcast=%s)\n",
- + namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
- +
- + debug_rr_type(nmb->answers->rr_type);
- +
- + n->num_msgs++; /* count number of responses received */
- + n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
- +
- + debug_state_type(n->state);
- +
- + /* problem checking: multiple responses etc */
- + if (response_problem_check(n, nmb, qname))
- + return;
- +
- + /* now check whether the 'state' has received the correct type of response */
- + if (!response_compatible(n, nmb))
- + return;
- +
- + /* now deal with the current state */
- + response_process(d, p, n, nmb, bcast, ans_name);
- +}
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservresp.doc samba-1.9.16alpha11/source/nameservresp.doc
- --- samba-1.9.16alpha10/source/nameservresp.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/nameservresp.doc Thu Jul 11 04:48:29 1996
- @@ -0,0 +1,164 @@
- +this module deals with the receipt of response packets. the
- +response packets are expected to be received, and there is a
- +record of this kept (see also: modules nameresp and namedbresp)
- +
- +point of interest to design purists: every function in this
- +module is static except response_netbios_packet().
- +
- +/*************************************************************************
- + response_netbios_packet()
- + *************************************************************************/
- +
- +this function receives netbios response packets. the samba server
- +(or a rogue tcp/ip system, or nmblookup) will have sent out a packet
- +requesting a response. a client (or a rogue tcp/ip system) responds
- +to that request.
- +
- +this function checks the validity of the packet it receives.
- +the expected response records are searched for the transaction id,
- +to see if it's a response expected by the samba server. if it isn't
- +it's reported as such, and ignored.
- +
- +if the response is found, then the subnet it was expected from will
- +also have been found. the subnet it actually came in on can be
- +checked against the subnet it was expected from and reported,
- +otherwise this function just carries on.
- +
- +the number of responses received is increased, and the number of
- +retries left to be sent is set to zero.
- +
- +after debug information is reported, and validation of the netbios
- +packet (e.g only one response from one machine is expected for some
- +functions) has occurred, the packet is processed. when the initial
- +request was sent out, the expected response record was flagged with,
- +for lack of a better word, a samba 'state' type. whenever a
- +response is received, the appropriate function is called to carry on
- +where the program control flow was interrupted while awaiting exactly
- +such a response.
- +
- +please note that _not_ receiving a response is dealt with in another
- +area of code - expire_netbios_response_entries().
- +
- +
- +/*************************************************************************
- + response_name_query_sync()
- + *************************************************************************/
- +
- +this function receives responses to samba 'states' NAME_QUERY_SYNC and
- +NAME_QUERY_CONFIRM.
- +
- +NAME_QUERY_SYNC: name query a server before synchronising browse lists.
- +NAME_QUERY_CONFIRM: name query a server to check that it's alive.
- +
- +a NAME_QUERY_SYNC will be carried out in order to check that a server
- +is alive before syncing browse lists. we don't want to delay the SMB
- +NetServerEnum api just because the server has gone down: we have too
- +much else to do.
- +
- +a NAME_QUERY_CONFIRM is just a name query to see whether the server is
- +alive. these queries are sent out by samba's WINS server side, to verify
- +its netbios name database of all machines that have registered with it.
- +
- +we don't normally expect a negative response from such a query, although
- +we may do so if the query was sent to another WINS server. the registered
- +entry should be removed if we receive a negative response.
- +
- +
- +/*************************************************************************
- + response_name_status_check()
- + *************************************************************************/
- +
- +this function receives responses to samba 'states' NAME_STATUS_CHECK
- +and NAME_STATUS_MASTER_CHECK
- +
- +NAME_STATUS_MASTER_CHECK: name status a primary domain controller,
- + confirm its domain and then initiate syncing
- + its browse list.
- +
- +NAME_STATUS_CHECK: same as NAME_STATUS_MASTER_CHECK except the name status
- + is issued to a master browser.
- +
- +if we don't know what workgroup a server is responsible for, but we
- +know that there is a master browser at a certain ip, we can issue a
- +name status check. from the response received, there will be
- +a master browser netbios entry. this will allow us to synchronise
- +browse lists with that machine and then add the information to the
- +correct part of samba's workgroup - server database.
- +
- +
- +/*************************************************************************
- + response_server_check()
- + *************************************************************************/
- +
- +this function receives responses to samba 'states' NAME_QUERY_MST_SRV_CHK,
- +NAME_QUERY_SRV_CHK and NAME_QUERY_FIND_MST.
- +
- +NAME_QUERY_FIND_MST: issued as a broadcast when we wish to find out all
- + master browsers (i.e all servers that have registered
- + the NetBIOS name ^1^2__MSBROWSE__^2(0x1), and then
- + issue a NAME_STATUS_MASTER_CHECK on any servers that
- + respond, which will initiate a sync browse lists.
- +
- +NAME_QUERY_MST_SRV_CHK: same as a NAME_QUERY_FIND_MST except this is sent
- + to a primary domain controller.
- +
- +NAME_QUERY_SRV_CHK: same as a NAME_QUERY_MST_SRV_CHK except this is sent to
- + a master browser.
- +
- +the purpose of each of these states is to do a broadcast name query, or
- +a name query directed at a WINS server, then to all hosts that respond,
- +we issue a name status check, which will confirm for us the workgroup
- +or domain name, and then initiate issuing a sync browse list call with
- +that server.
- +
- +a NAME_QUERY_SRV_CHK is sent when samba receives a list of backup
- +browsers. it checks to see if that server is alive (by doing a
- +name query on a server) and then syncs browse lists with it.
- +
- +
- +/*************************************************************************
- + response_name_reg()
- + *************************************************************************/
- +
- +this function is responsible for dealing with samba's registration
- +attempts, by broadcast to a local subnet, or point-to-point with
- +another WINS server.
- +
- +please note that it cannot cope with END-NODE CHALLENGE REGISTRATION
- +RESPONSEs at present.
- +
- +when a response is received, samba determines if the response is a
- +positive or a negative one. if it is a positive response, the name
- +is added to samba's database.
- +
- +when a negative response is received, samba will remove the name
- +from its database. if, however, the name is a browser type (0x1b is
- +a primary domain controller type name; or 0x1d, which is a master
- +browser type name) then it must also stop being a primary domain
- +controller or master browser respectively, depending on what kind
- +of name was rejected.
- +
- +(when no response is received, then expire_netbios_response_entries()
- +is expected to deal with this. the only case that is dealt with here
- +at present is when the registration was done by broadcast. if there
- +is no challenge to the broadcast registration, it is implicitly
- +assumed that claiming the name is acceptable).
- +
- +
- +/*************************************************************************
- + response_name_release()
- + *************************************************************************/
- +
- +this function is responsible for removing samba's NetBIOS name when
- +samba contacts another WINS server with which it had registered the
- +name.
- +
- +only positive name releases are expected and dealt with. exactly what
- +to do if a negative name release (i.e someone says 'oi! you have to
- +keep that name!') is received is uncertain.
- +
- +(when no response is received, then expire_netbios_response_entries()
- +is expected to deal with this. if there is no challenge to the release
- +of the name, the name is then removed from that subnet's NetBIOS
- +name database).
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namework.c samba-1.9.16alpha11/source/namework.c
- --- samba-1.9.16alpha10/source/namework.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/namework.c Thu Jul 18 20:53:16 1996
- @@ -2,7 +2,7 @@
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- - Copyright (C) Andrew Tridgell 1994-1995
- + Copyright (C) Andrew Tridgell 1994-1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- @@ -45,9 +45,6 @@
-
- extern int workgroup_count; /* total number of workgroups we know about */
-
- -/* this is our browse cache database */
- -extern struct browse_cache_record *browserlist;
- -
- /* this is our domain/workgroup/server database */
- extern struct subnet_record *subnetlist;
-
- @@ -67,13 +64,7 @@
-
- extern time_t StartupTime;
-
- -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
- -#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
- -
- -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
- -
- -#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
- -
- +extern BOOL updatedlists;
-
- /****************************************************************************
- tell a server to become a backup browser
- @@ -106,6 +97,11 @@
- **************************************************************************/
- void tell_become_backup(void)
- {
- + /* XXXX note: this function is currently unsuitable for use, as it
- + does not properly check that a server is in a fit state to become
- + a backup browser before asking it to be one.
- + */
- +
- struct subnet_record *d;
- for (d = subnetlist; d; d = d->next)
- {
- @@ -155,266 +151,6 @@
- }
- }
-
- -/****************************************************************************
- -find a server responsible for a workgroup, and sync browse lists
- -**************************************************************************/
- -static BOOL sync_browse_entry(struct browse_cache_record *b)
- -{
- - struct subnet_record *d;
- - struct work_record *work;
- - /*
- - if (!strequal(serv_name, b->name))
- - {
- - DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
- - b->name, inet_ntoa(b->ip), serv_name));
- - }
- - */
- - if (!(d = find_domain(b->ip))) return False;
- - if (!(work = find_workgroupstruct(d, b->group, False))) return False;
- -
- - if (AM_MASTER(work)) {
- - /* only try to sync browse lists if we are the master, otherwise
- - the net could get a little bit too busy */
- - sync_browse_lists(work,b->name,0x20,b->ip);
- - }
- - b->synced = True;
- -
- - return True;
- -}
- -
- -
- -/****************************************************************************
- -search through browser list for an entry to sync with
- -**************************************************************************/
- -void do_browser_lists(void)
- -{
- - struct browse_cache_record *b;
- - static time_t last = 0;
- - time_t t = time(NULL);
- -
- - if (t-last < 20) return; /* don't do too many of these at once! */
- -
- - last = t;
- -
- - /* pick any entry in the list, preferably one whose time is up */
- - for (b = browserlist; b && b->next; b = b->next)
- - {
- - if (b->sync_time < t && b->synced == False) break;
- - }
- -
- - if (!b || b->synced || sync_browse_entry(b))
- - {
- - /* leave entries (even ones already sync'd) for up to a minute.
- - this stops them getting re-sync'd too often */
- - expire_browse_cache(t - 60);
- - }
- -}
- -
- -
- -/****************************************************************************
- -find a server responsible for a workgroup, and sync browse lists
- -control ends up back here via response_name_query.
- -**************************************************************************/
- -void sync_server(enum cmd_type cmd, char *serv_name, char *work_name,
- - int name_type,
- - struct in_addr ip)
- -{
- - add_browser_entry(serv_name, name_type, work_name, 0, ip);
- -
- - if (cmd == MASTER_SERVER_CHECK)
- - {
- - /* announce ourselves as a master browser to serv_name */
- - do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
- - 0x20, 0, ip);
- - }
- -}
- -
- -
- -/****************************************************************************
- -update workgroup database from a name registration
- -**************************************************************************/
- -void update_from_reg(char *name, int type, struct in_addr ip)
- -{
- - /* default server type: minimum guess at requirement XXXX */
- -
- - DEBUG(3,("update from registration: host %s ip %s type %0x\n",
- - name, inet_ntoa(ip), type));
- -
- - /* workgroup types, but not a chat type */
- - if (type >= 0x1b && type <= 0x1e)
- - {
- - struct work_record *work;
- - struct subnet_record *d;
- -
- - if (!(d = find_domain(ip))) return;
- - if (!(work = find_workgroupstruct(d, name, False))) return;
- -
- - /* request the server to announce if on our subnet */
- - if (d->my_interface) announce_request(work, ip);
- -
- - /* domain master type or master browser type */
- - if (type == 0x1b || type == 0x1d)
- - {
- - struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
- - if (hp) {
- - /* gethostbyaddr name may not match netbios name but who cares */
- - add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
- - }
- - }
- - }
- -}
- -
- -
- -/****************************************************************************
- - add the default workgroup into my domain
- - **************************************************************************/
- -void add_my_domains(char *group)
- -{
- - int n,i;
- - struct in_addr *ip;
- -
- - if (*group == '*') return;
- -
- - n = iface_count();
- - for (i=0;i<n;i++) {
- - ip = iface_n_ip(i);
- - if (!ip) return;
- - add_subnet_entry(*iface_bcast(*ip),*iface_nmask(*ip),lp_workgroup(),True);
- - }
- -}
- -
- -
- -/****************************************************************************
- - send a backup list response.
- - **************************************************************************/
- -static void send_backup_list(char *work_name, struct nmb_name *src_name,
- - int info_count, int token, int info,
- - int name_type, struct in_addr ip)
- -{
- - struct subnet_record *d;
- - char outbuf[1024];
- - char *p, *countptr, *nameptr;
- - int count = 0;
- - int i, j;
- - char *theirname = src_name->name;
- -
- - DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
- - work_name, inet_ntoa(ip),
- - myname,0x20,theirname,0x0));
- -
- - if (name_type == 0x1d)
- - {
- - DEBUG(4,("master browsers: "));
- - }
- - else if (name_type == 0x1b)
- - {
- - DEBUG(4,("domain controllers: "));
- - }
- - else
- - {
- - DEBUG(0,("backup request for unknown type %0x\n", name_type));
- - return;
- - }
- -
- - bzero(outbuf,sizeof(outbuf));
- - p = outbuf;
- -
- - CVAL(p,0) = 10; /* backup list response */
- - p++;
- -
- - countptr = p; /* count pointer */
- -
- - SSVAL(p,1,token); /* sender's workgroup index representation */
- - SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
- - p += 5;
- -
- - nameptr = p;
- -
- - for (d = subnetlist; d; d = d->next)
- - {
- - struct work_record *work;
- -
- - for (work = d->workgrouplist; work; work = work->next)
- - {
- - struct server_record *s;
- -
- - if (!strequal(work->work_group, work_name)) continue;
- -
- - for (s = work->serverlist; s; s = s->next)
- - {
- - BOOL found = False;
- - char *n;
- -
- - if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
- -
- - for (n = nameptr; n < p; n = skip_string(n, 1))
- - {
- - if (strequal(n, s->serv.name)) found = True;
- - }
- -
- - if (found) continue; /* exclude names already added */
- -
- - /* workgroup request: include all backup browsers in the list */
- - /* domain request: include all domain members in the list */
- -
- - if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
- - (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
- - {
- - DEBUG(4, ("%s ", s->serv.name));
- -
- - count++;
- - strcpy(p,s->serv.name);
- - strupper(p);
- - p = skip_string(p,1);
- - }
- - }
- - }
- - }
- -
- - if (count == 0)
- - {
- - DEBUG(4, ("none\n"));
- - return;
- - }
- - else
- - {
- - DEBUG(4, (" - count %d\n", count));
- - }
- -
- - CVAL(countptr,0) = count; /* total number of backup browsers found */
- -
- - {
- - int len = PTR_DIFF(p, outbuf);
- -
- - for (i = 0; i < len; i+= 16)
- - {
- - DEBUG(4, ("%3x char ", i));
- -
- - for (j = 0; j < 16; j++)
- - {
- - unsigned char x = outbuf[i+j];
- - if (x < 32 || x > 127) x = '.';
- -
- - if (i+j >= len) break;
- - DEBUG(4, ("%c", x));
- - }
- -
- - DEBUG(4, (" hex ", i));
- -
- - for (j = 0; j < 16; j++)
- - {
- - if (i+j >= len) break;
- - DEBUG(4, (" %02x", outbuf[i+j]));
- - }
- -
- - DEBUG(4, ("\n"));
- - }
- -
- - }
- - send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- - myname,theirname,0x20,0,ip,*iface_ip(ip));
- -}
- -
-
- /*******************************************************************
- same context: scope. should check name_type as well, and makes sure
- @@ -460,18 +196,22 @@
- resources. We just have to pass it to smbd (via browser.dat) and let
- the client choose using bit masks.
- ******************************************************************/
- -static void process_announce(struct packet_struct *p,int command,char *buf)
- +static void process_announce(struct packet_struct *p,uint16 command,char *buf)
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d = find_domain(ip);
- + struct subnet_record *d = find_subnet(ip);
- int update_count = CVAL(buf,0);
- +
- int ttl = IVAL(buf,1)/1000;
- char *name = buf+5;
- int osmajor=CVAL(buf,21);
- int osminor=CVAL(buf,22);
- uint32 servertype = IVAL(buf,23);
- + uint32 browse_type= CVAL(buf,27);
- + uint32 browse_sig = CVAL(buf,29);
- char *comment = buf+31;
- +
- struct work_record *work;
- char *work_name;
- char *serv_name = dgram->source_name.name;
- @@ -480,9 +220,9 @@
- comment[43] = 0;
-
- DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
- - DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
- + DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
- namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
- - servertype,comment));
- + servertype,browse_type,browse_sig,comment));
-
- name[15] = 0;
-
- @@ -501,10 +241,20 @@
- return;
- }
-
- - if (same_context(dgram)) return;
- + if (!strequal(dgram->dest_name.scope,scope )) return;
-
- - if (command == ANN_DomainAnnouncement) {
- + if (command == ANN_DomainAnnouncement) {
- + /* XXXX if we are a master browser for the workgroup work_name,
- + then there is a local subnet configuration problem. only
- + we should be sending out such domain announcements, because
- + as the master browser, that is our job.
- +
- + stop being a master browser, and force an election. this will
- + sort out the network problem. hopefully.
- + */
- +
- work_name = name;
- + add = True;
- } else {
- work_name = dgram->dest_name.name;
- }
- @@ -524,15 +274,24 @@
-
- ttl = GET_TTL(ttl);
-
- - /* add them to our browse list */
- + /* add them to our browse list, and update the browse.dat file */
- add_server_entry(d,work,name,servertype,ttl,comment,True);
- -
- + updatedlists = True;
- +
- #if 0
- /* the tell become backup code is broken, no great harm is done by
- disabling it */
- tell_become_backup();
- #endif
-
- + /* XXXX over-kill: i don't think we should really be doing this,
- + but it doesn't do much harm other than to add extra network
- + traffic. to be more precise, we should (possibly) only
- + sync browse lists with a host that sends an
- + ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement.
- + possibly.
- + */
- +
- /* get their browse list from them and add it to ours. */
- add_browser_entry(serv_name,dgram->dest_name.name_type,
- work->work_group,30,ip);
- @@ -545,8 +304,8 @@
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d = find_domain(ip);
- - struct subnet_record *mydomain = find_domain(*iface_bcast(ip));
- + struct subnet_record *d = find_subnet(ip);
- + struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
- char *name = buf;
- struct work_record *work;
- name[15] = 0;
- @@ -575,18 +334,24 @@
- we receive a list of servers, and we attempt to locate them all on
- our local subnet, and sync browse lists with them on the workgroup
- they are said to be in.
- +
- + XXXX NOTE: this function is in overdrive. it should not really do
- + half of what it actually does (it should pick _one_ name from the
- + list received and sync with it at regular intervals, rather than
- + sync with them all only once!)
- +
- ******************************************************************/
- static void process_rcv_backup_list(struct packet_struct *p,char *buf)
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- int count = CVAL(buf,0);
- - int Index = IVAL(buf,1); /* caller's index representing workgroup */
- + uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
- char *buf1;
-
- - DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
- + DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
- namestr(&dgram->dest_name), inet_ntoa(ip),
- - count, Index));
- + count, info));
-
- if (same_context(dgram)) return;
-
- @@ -594,50 +359,170 @@
-
- /* go through the list of servers attempting to sync browse lists */
- for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
- - {
- - struct in_addr back_ip;
- - struct subnet_record *d;
- + {
- + struct in_addr back_ip;
- + struct subnet_record *d;
-
- - DEBUG(4,("Searching for backup browser %s at %s...\n",
- + DEBUG(4,("Searching for backup browser %s at %s...\n",
- buf1, inet_ntoa(ip)));
-
- - /* XXXX assume name is a DNS name NOT a netbios name. a more complete
- - approach is to use reply_name_query functionality to find the name */
- - back_ip = *interpret_addr2(buf1);
- + /* XXXX assume name is a DNS name NOT a netbios name. a more complete
- + approach is to use reply_name_query functionality to find the name */
- +
- + back_ip = *interpret_addr2(buf1);
-
- - if (zero_ip(back_ip))
- + if (zero_ip(back_ip))
- {
- DEBUG(4,("Failed to find backup browser server using DNS\n"));
- continue;
- }
-
- DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
- + DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
-
- - if ((d = find_domain(back_ip)))
- + /* XXXX function needs work */
- + continue;
- +
- + if ((d = find_subnet(back_ip)))
- {
- struct subnet_record *d1;
- for (d1 = subnetlist; d1; d1 = d1->next)
- - {
- + {
- struct work_record *work;
- for (work = d1->workgrouplist; work; work = work->next)
- {
- - if (work->token == Index)
- - {
- - queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
- - work->work_group,0x1d,0,
- - False,False,back_ip);
- + if (work->token == 0 /* token */)
- + {
- + queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
- + work->work_group,0x1d,0,0,
- + False,False,back_ip,back_ip);
- return;
- - }
- + }
- }
- - }
- + }
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- + send a backup list response.
- + **************************************************************************/
- +static void send_backup_list(char *work_name, struct nmb_name *src_name,
- + int token, uint32 info,
- + int name_type, struct in_addr ip)
- +{
- + char outbuf[1024];
- + char *p, *countptr, *nameptr;
- + int count = 0;
- + char *theirname = src_name->name;
- +
- + DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
- + work_name, inet_ntoa(ip),
- + myname,0x0,theirname,0x0));
- +
- + if (name_type == 0x1d)
- + {
- + DEBUG(4,("master browsers: "));
- + }
- + else if (name_type == 0x1b)
- + {
- + DEBUG(4,("domain controllers: "));
- + }
- + else
- + {
- + DEBUG(0,("backup request for unknown type %0x\n", name_type));
- + return;
- + }
- +
- + bzero(outbuf,sizeof(outbuf));
- + p = outbuf;
- +
- + CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */
- +
- + p++;
- + countptr = p;
- +
- + SIVAL(p,1,info); /* the sender's unique info */
- +
- + p += 5;
- +
- + nameptr = p;
- +
- +#if 0
- +
- + for (d = subnetlist; d; d = d->next)
- + {
- + struct work_record *work;
- +
- + for (work = d->workgrouplist; work; work = work->next)
- + {
- + struct server_record *s;
- +
- + if (!strequal(work->work_group, work_name)) continue;
- +
- + for (s = work->serverlist; s; s = s->next)
- + {
- + BOOL found = False;
- + char *n;
- +
- + if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
- +
- + for (n = nameptr; n < p; n = skip_string(n, 1))
- + {
- + if (strequal(n, s->serv.name)) found = True;
- + }
- +
- + if (found) continue; /* exclude names already added */
- +
- + /* workgroup request: include all backup browsers in the list */
- + /* domain request: include all domain members in the list */
- +
- + if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
- + (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
- + {
- + DEBUG(4, ("%s ", s->serv.name));
- +
- + count++;
- + strcpy(p,s->serv.name);
- + strupper(p);
- + p = skip_string(p,1);
- + }
- + }
- }
- + }
- +
- +#endif
- +
- + count++;
- + strcpy(p,myname);
- + strupper(p);
- + p = skip_string(p,1);
- +
- + if (count == 0)
- + {
- + DEBUG(4, ("none\n"));
- + }
- + else
- + {
- + DEBUG(4, (" - count %d\n", count));
- }
- +
- + CVAL(countptr, 0) = count;
- +
- + {
- + int len = PTR_DIFF(p, outbuf);
- + debug_browse_data(outbuf, len);
- + }
- + send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- + myname,theirname,0x0,0x0,ip,*iface_ip(ip));
- }
-
- +
- /*******************************************************************
- process a send backup list request
-
- - A client send a backup list request to ask for a list of servers on
- + A client sends a backup list request to ask for a list of servers on
- the net that maintain server lists for a domain. A server is then
- chosen from this list to send NetServerEnum commands to to list
- available servers.
- @@ -650,18 +535,15 @@
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d;
- + struct subnet_record *d;
- struct work_record *work;
-
- - int count = CVAL(buf,0);
- - int token = SVAL(buf,1); /* sender's key index for the workgroup? */
- - int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
- + int token = CVAL(buf,0); /* sender's key index for the workgroup */
- + uint32 info = IVAL(buf,1); /* XXXX don't know: some sort of info */
- int name_type = dgram->dest_name.name_type;
-
- if (same_context(dgram)) return;
-
- - if (count <= 0) return;
- -
- if (name_type != 0x1b && name_type != 0x1d) {
- DEBUG(0,("backup request to wrong type %d from %s\n",
- name_type,inet_ntoa(ip)));
- @@ -674,11 +556,11 @@
- {
- if (strequal(work->work_group, dgram->dest_name.name))
- {
- - DEBUG(2,("sending backup list to %s %s count=%d\n",
- - namestr(&dgram->dest_name),inet_ntoa(ip),count));
- + DEBUG(2,("sending backup list to %s %s id=%x\n",
- + namestr(&dgram->dest_name),inet_ntoa(ip),info));
-
- send_backup_list(work->work_group,&dgram->source_name,
- - count,token,info,name_type,ip);
- + token,info,name_type,ip);
- return;
- }
- }
- @@ -690,7 +572,7 @@
- process a reset browser state
-
- diagnostic packet:
- - 0x1 - stop being a master browser
- + 0x1 - stop being a master browser and become a backup browser.
- 0x2 - discard browse lists, stop being a master browser, try again.
- 0x4 - stop being a master browser forever. no way. ain't gonna.
-
- @@ -714,12 +596,16 @@
- {
- if (AM_MASTER(work))
- {
- - become_nonmaster(d,work);
- + become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
- }
- }
- }
- }
-
- + /* XXXX documentation inconsistency: the above description does not
- + exactly tally with what is implemented for state & 0x2
- + */
- +
- /* totally delete all servers and start afresh */
- if (state & 0x2)
- {
- @@ -727,9 +613,9 @@
- for (d = subnetlist; d; d = d->next)
- {
- struct work_record *work;
- - for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
- + for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
- }
- - add_my_domains(lp_workgroup());
- + add_my_subnets(lp_workgroup());
- }
-
- /* stop browsing altogether. i don't think this is a good idea! */
- @@ -739,7 +625,6 @@
- }
- }
-
- -
- /*******************************************************************
- process a announcement request
-
- @@ -751,7 +636,7 @@
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d = find_domain(ip);
- + struct subnet_record *d = find_subnet(ip);
- int token = CVAL(buf,0);
- char *name = buf+1;
-
- @@ -762,12 +647,23 @@
-
- if (strequal(dgram->source_name.name,myname)) return;
-
- + /* XXXX BUG or FEATURE?: need to ensure that we are a member of
- + this workgroup before announcing, particularly as we only
- + respond on local interfaces anyway.
- +
- + if (strequal(dgram->dest_name, lp_workgroup()) return; ???
- + */
- +
- if (!d) return;
-
- if (!d->my_interface) return;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- + /* XXXX BUG: the destination name type should also be checked,
- + not just the name. e.g if the name is WORKGROUP(0x1d) then
- + we should only respond if we own that name */
- +
- if (strequal(dgram->dest_name.name,work->work_group))
- {
- work->needannounce = True;
- @@ -777,89 +673,6 @@
-
-
- /****************************************************************************
- - process a domain logon packet
- - **************************************************************************/
- -void process_logon_packet(struct packet_struct *p,char *buf,int len)
- -{
- - struct dgram_packet *dgram = &p->packet.dgram;
- - struct in_addr ip = dgram->header.source_ip;
- - struct subnet_record *d = find_domain(ip);
- - char *logname,*q;
- - char *reply_name;
- - BOOL add_slashes = False;
- - pstring outbuf;
- - int code,reply_code;
- - struct work_record *work;
- -
- - if (!d) return;
- -
- - if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
- - return;
- -
- - if (!lp_domain_logons()) {
- - DEBUG(3,("No domain logons\n"));
- - return;
- - }
- - if (!listening_name(work, &dgram->dest_name))
- - {
- - DEBUG(4,("Not listening to that domain\n"));
- - return;
- - }
- -
- - code = SVAL(buf,0);
- - switch (code) {
- - case 0:
- - {
- - char *machine = buf+2;
- - char *user = skip_string(machine,1);
- - logname = skip_string(user,1);
- - reply_code = 6;
- - reply_name = myname;
- - add_slashes = True;
- - DEBUG(3,("Domain login request from %s(%s) user=%s\n",
- - machine,inet_ntoa(p->ip),user));
- - }
- - break;
- - case 7:
- - {
- - char *machine = buf+2;
- - logname = skip_string(machine,1);
- - reply_code = 7;
- - reply_name = lp_domain_controller();
- - if (!*reply_name) {
- - DEBUG(3,("No domain controller configured\n"));
- - return;
- - }
- - DEBUG(3,("GETDC request from %s(%s)\n",
- - machine,inet_ntoa(p->ip)));
- - }
- - break;
- - default:
- - DEBUG(3,("Unknown domain request %d\n",code));
- - return;
- - }
- -
- - bzero(outbuf,sizeof(outbuf));
- - q = outbuf;
- - SSVAL(q,0,reply_code);
- - q += 2;
- - if (add_slashes) {
- - strcpy(q,"\\\\");
- - q += 2;
- - }
- - StrnCpy(q,reply_name,16);
- - strupper(q);
- - q = skip_string(q,1);
- - SSVAL(q,0,0xFFFF);
- - q += 2;
- -
- - send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
- - myname,&dgram->source_name.name[0],0x20,0,p->ip,
- - *iface_ip(p->ip));
- -}
- -
- -
- -/****************************************************************************
- depending on what announce has been made, we are only going to
- accept certain types of name announce. XXXX untested code
-
- @@ -936,6 +749,7 @@
- case ANN_DomainAnnouncement:
- case ANN_LocalMasterAnnouncement:
- {
- + debug_browse_data(buf, len);
- process_announce(p,command,buf+1);
- break;
- }
- @@ -954,15 +768,17 @@
-
- case ANN_GetBackupListReq:
- {
- + debug_browse_data(buf, len);
- process_send_backup_list(p,buf+1);
- break;
- }
-
- case ANN_GetBackupListResp:
- - {
- - process_rcv_backup_list(p, buf+1);
- - break;
- - }
- + {
- + debug_browse_data(buf, len);
- + process_rcv_backup_list(p, buf+1);
- + break;
- + }
-
- case ANN_ResetBrowserState:
- {
- @@ -986,45 +802,4 @@
- }
- }
-
- -
- -/****************************************************************************
- -process udp 138 datagrams
- -****************************************************************************/
- -void process_dgram(struct packet_struct *p)
- -{
- - char *buf;
- - char *buf2;
- - int len;
- - struct dgram_packet *dgram = &p->packet.dgram;
- -
- - if (dgram->header.msg_type != 0x10 &&
- - dgram->header.msg_type != 0x11 &&
- - dgram->header.msg_type != 0x12) {
- - /* don't process error packets etc yet */
- - return;
- - }
- -
- - buf = &dgram->data[0];
- - buf -= 4; /* XXXX for the pseudo tcp length -
- - someday I need to get rid of this */
- -
- - if (CVAL(buf,smb_com) != SMBtrans) return;
- -
- - len = SVAL(buf,smb_vwv11);
- - buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
- -
- - DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
- - namestr(&dgram->source_name),namestr(&dgram->dest_name),
- - smb_buf(buf),CVAL(buf2,0),len));
- -
- -
- - if (len <= 0) return;
- -
- - if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
- - {
- - process_browse_packet(p,buf2,len);
- - } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
- - process_logon_packet(p,buf2,len);
- - }
- -}
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namework.doc samba-1.9.16alpha11/source/namework.doc
- --- samba-1.9.16alpha10/source/namework.doc Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/namework.doc Sun Jul 7 22:35:58 1996
- @@ -0,0 +1,287 @@
- +
- +the module namework.c deals with NetBIOS datagram packets, primarily.
- +it deals with nmbd's workgroup browser side and the domain log in
- +side. none of the functionality here has specification documents available.
- +empirical observation of packet traces has been the order of the day,
- +along with some guess-work.
- +
- +beware!
- +
- +the receipt of datagram packets for workgroup browsing are dealt with here.
- +some of the functions listed here will call others outside of this
- +module, or will activate functionality dealt with by other modules
- +(namedb, nameannounce, nameelect, namelogon, and namebrowse).
- +
- +
- +/*************************************************************************
- + process_browse_packet()
- + *************************************************************************/
- +
- +this function is responsible for further identifying which type of
- +browser datagram packet has been received, and dealing with it
- +accordingly. if the packet is not dealt with, then an error is
- +logged along with the type of packet that has been received.
- +
- +if listening_type() was in use, then it would be used here.
- +
- +the types of packets received and dealt with are:
- +
- +- ANN_HostAnnouncement
- +- ANN_DomainAnnouncement
- +- ANN_LocalMasterAnnouncement
- +
- +these are all identical in format and can all be processed by
- +process_announce(). an announcement is received from a host
- +(either a master browser telling us about itself, a server
- +telling us about itself or a master browser telling us about
- +a domain / workgroup)
- +
- +- ANN_AnnouncementRequest
- +
- +these are sent by master browsers or by servers. it is a
- +request to announce ourselves as appropriate by sending
- +either a ANN_HostAnnouncement datagram or both an
- +ANN_DomainAnnouncement and an ANN_LocalMasterAnnouncement
- +if we are a master browser (but not both).
- +
- +- ANN_Election
- +
- +this is an election datagram. if samba has been configured
- +as a domain master then it will also send out election
- +datagrams.
- +
- +- ANN_GetBackupListReq
- +
- +this is a request from another server for us to send a
- +backup list of all servers that we know about. we respond
- +by sending a datagram ANN_GetBackupListResp. the protocol
- +here is a little dicey.
- +
- +- ANN_GetBackupListResp
- +
- +this is a response from another server that we have sent an
- +ANN_GetBackupListReq to. the protocol is a little dicey.
- +
- +- ANN_BecomeBackup
- +
- +this is a message sent by a primary domain controller to a
- +potential master browser, indicating that it should become
- +a backup master browser for the workgroup it is a member
- +of. samba does not respond at present to such datagrams,
- +and it also sends out such datagrams for the wrong reasons
- +(this code has now been disabled until this is fixed).
- +
- +- ANN_ResetBrowserState
- +
- +this datagram is sent by a primary domain controller (or
- +anyone else, for that matter) for trouble-shooting purposes.
- +it asks a browser to clear out its server lists, or to
- +stop becoming a master browser altogether. NT/AS and
- +samba do not implement this latter option.
- +
- +- ANN_MasterAnnouncement
- +
- +this datagram is sent by a master browser to a primary domain
- +controller. it is a way to ensure that master browsers are
- +kept in sync with a primary domain controller across a wide
- +area network. on receipt of an ANN_MasterAnnouncement we
- +should sync browse lists with the sender.
- +
- +(i never got the hang of this one when i was experimenting.
- +i forget exactly what it's for, and i never fully worked
- +out how to coax a server to send it. :-)
- +
- +
- +/*************************************************************************
- + listening_type()
- + *************************************************************************/
- +
- +
- +a datagram packet is sent from one NetBIOS name of a specific type
- +to another NetBIOS name of a specific type. certain types of
- +datagrams are only expected from certain types of NetBIOS names.
- +
- +this function is intended to catch errors in the type of datagrams
- +received from different NetBIOS names. it is currently incomplete
- +due to lack of information on the types of names and the datagrams
- +they send.
- +
- +
- +/*************************************************************************
- + process_announce_request()
- + *************************************************************************/
- +
- +this function is responsible for dealing with announcement requests.
- +if the type of name that the request is sent to matches our current
- +status, then we should respond. otherwise, the datagram should be
- +ignored.
- +
- +samba only responds on its local subnets.
- +
- +at present, just the name is checked to see if the packet is for us.
- +what should be done is that if we own the name (e.g WORGROUP(0x1d)
- +or WORKGROUP(0x1b) then we should respond, otherwise, ignore the
- +datagram.
- +
- +if the name is for us, and we are a member of that workgroup, then
- +samba should respond.
- +
- +note that samba does not respond immediately. this is to ensure that
- +if the master browser for the workgroup that samba is a member of
- +sends out a broadcast request announcement, that that master browser
- +is not swamped with replies. it is therefore up to samba to reply
- +at some random interval. hence, a flag is set indicating the need
- +to announce later.
- +
- +
- +/*************************************************************************
- + process_reset_browser()
- + *************************************************************************/
- +
- +this function is responsible for dealing with reset state datagrams.
- +there are three kinds of diagnostic reset requests:
- +
- +- stop being a master browser
- +- discard browse lists, stop being a master browser, and run for re-election
- +- stop being a master browser forever.
- +
- +samba and windows nt do not implement the latter option.
- +
- +there appears to be a discrepancy between this description and the
- +code actually implemented.
- +
- +
- +/*************************************************************************
- + process_send_backup_list()
- + *************************************************************************/
- +
- +this function is part of samba's primary domain controller functionality.
- +
- +it is responsible for giving master browsers a list of other browsers
- +that maintain backup lists of servers for that master browser's workgroup.
- +
- +it is also responsible for giving master browsers a list of primary domain
- +controllers for that master browser's domain.
- +
- +a correct way to think of this function is that it is a 'request to
- +send out a backup list for the requested workgroup or domain'.
- +
- +i have some suspicions and intuitions about this function and how it
- +is to actually be used. there is no documentation on this, so it is a
- +matter of experimenting until it's right.
- +
- +
- +/*************************************************************************
- + send_backup_list()
- + *************************************************************************/
- +
- +this function is responsible for compiling a list of either master
- +browsers and backup master browsers or primary domain controllers or
- +backup domain controllers. samba constructs this list from its
- +workgroup / server database.
- +
- +the list is then sent to the host that requested it by sending an
- +ANN_GetBackupListResp datagram to this host.
- +
- +
- +/*************************************************************************
- + process_rcv_backup_list()
- + *************************************************************************/
- +
- +this function is implemented with a slightly over-kill algorithm.
- +the correct functionality is to pick any three names at random from
- +the list that is received from this datagram, and then at intervals
- +contact _one_ of them for a list of browser, in order to update
- +samba's browse list.
- +
- +samba contacts every single one of the backup browsers listed, through
- +the use of a NAME_QUERY_SRV_CHK 'state'.
- +
- +
- +/*************************************************************************
- + process_master_announce()
- + *************************************************************************/
- +
- +this function is responsible for synchronising browse lists with a
- +master browser that contacts samba in its capacity as a primary
- +domain controller.
- +
- +the function add_browser_entry() is used to add the server that
- +contacts us to our list of browser to sync browse lists with at
- +some point in the near future.
- +
- +
- +/*************************************************************************
- + process_announce()
- + *************************************************************************/
- +
- +this function is responsible for dealing with the three types of
- +announcement type datagrams that samba recognises. some appropriate
- +type-checking is done on the name that the datagram is sent to.
- +
- +samba does not at present deal with LanManager announcements.
- +
- +these announcements are for updating the browse entry records.
- +each browse entry has a time-to-live associated with it. each server
- +must refresh its entry with all other servers by broadcasting
- +Announcements. if it does not do so, then other servers will not
- +know about that machine, and the records on each server of that
- +other machine will die.
- +
- +if an ANN_DomainAnnouncement is received, then this will be from
- +a master browser. only one machine on any given broadcast area (e.g
- +a subnet) should be broadcasting such announcements. the information
- +it contains tells other servers that there is a master browser for
- +this workgroup. if another server thinks that it is also a master
- +browser for the same workgroup, then it should stop being a master
- +browser and force an election.
- +
- +if an ANN_LocalMasterAnnouncement is received, then a master browser
- +is telling us that it exists. i am uncertain that anything else
- +actually needs to be done with this, other than to shout 'hooray' and
- +'thank you for informing me of this fact'.
- +
- +
- +/*************************************************************************
- + listening_name()
- + *************************************************************************/
- +
- +this function is an over-simplified way of identifying whether we
- +should be responding to a datagram that has been received.
- +
- +
- +/*************************************************************************
- + same_context()
- + *************************************************************************/
- +
- +this function helps us to identify whether we should be responding to
- +a datagram that has been received.
- +
- +
- +/*************************************************************************
- + tell_become_backup()
- + *************************************************************************/
- +
- +this function is part of samba's primary domain controller capabilities.
- +it is responsible for finding appropriate servers to tell to become a
- +backup master browser for the domain that samba controls.
- +
- +other servers that contact samba asking for a list of backup browsers
- +will then be given that server's name, and that server can expect to
- +receive NetServerEnum requests for lists of servers and workgroups.
- +
- +this function must be updated before it is in a fit state to be used.
- +it must properly check whether a server is prepared to become a backup
- +browser before actually asking it to be one.
- +
- +
- +/*************************************************************************
- + reset_server()
- + *************************************************************************/
- +
- +this function is responsible for issuing an ANN_ResetBrowserState to
- +the specified server, asking it to reset its browser information.
- +
- +see process_reset_browser() for details on this function.
- +
- +
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmbd.c samba-1.9.16alpha11/source/nmbd.c
- --- samba-1.9.16alpha10/source/nmbd.c Mon Jun 10 15:18:56 1996
- +++ samba-1.9.16alpha11/source/nmbd.c Thu Jul 18 20:53:16 1996
- @@ -55,21 +55,24 @@
-
-
- /****************************************************************************
- -catch a sigterm
- -****************************************************************************/
- + catch a sigterm
- + ****************************************************************************/
- static int sig_term()
- {
- BlockSignals(True);
-
- DEBUG(0,("Got SIGTERM: going down...\n"));
-
- + /* write out wins.dat file if samba is a WINS server */
- dump_names();
- - reload_services(True);
-
- /* remove all samba names, with wins server if necessary. */
- remove_my_names();
-
- + /* announce all server entries as 0 time-to-live, 0 type */
- /* XXXX don't care if we never receive a response back... yet */
- + remove_my_servers();
- +
- /* XXXX other things: if we are a master browser, force an election? */
-
- exit(0);
- @@ -204,6 +207,7 @@
- }
-
- load_interfaces();
- + add_subnet_interfaces();
-
- return(ret);
- }
- @@ -286,9 +290,13 @@
- ipmask = *iface_nmask(ipaddr);
-
- if (group) {
- - add_subnet_entry(ipaddr, ipmask, name, True);
- + add_subnet_entry(ipaddr, ipmask, name, True, True);
- } else {
- - add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr,True);
- + struct subnet_record *d = find_subnet(ipaddr);
- + if (d)
- + {
- + add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
- + }
- }
- }
- }
- @@ -315,17 +323,20 @@
-
- announce_host();
-
- -#if 0
- - /* what was this stuff supposed to do? It sent
- +#if 1
- + /* XXXX what was this stuff supposed to do? It sent
- ANN_GetBackupListReq packets which I think should only be
- sent when trying to find out who to browse with */
- +
- announce_backup();
- #endif
-
- announce_master();
-
- + query_refresh_names();
- +
- expire_names_and_servers();
- - expire_netbios_response_entries(t-10);
- + expire_netbios_response_entries();
- refresh_my_names(t);
-
- write_browse_list();
- @@ -446,7 +457,7 @@
-
- fault_setup(fault_continue);
-
- - signal(SIGHUP,SIGNAL_CAST sig_hup);
- + signal(SIGHUP ,SIGNAL_CAST sig_hup);
- signal(SIGTERM,SIGNAL_CAST sig_term);
-
- while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
- @@ -514,7 +525,7 @@
- return(-1);
-
- if (*group)
- - add_my_domains(group);
- + add_my_subnets(group);
-
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- @@ -535,16 +546,22 @@
- DEBUG(3,("Loaded hosts file\n"));
- }
-
- +
- +
- if (!*ServerComment)
- strcpy(ServerComment,"Samba %v");
- string_sub(ServerComment,"%v",VERSION);
- string_sub(ServerComment,"%h",myhostname);
-
- add_my_names();
- - add_my_domains(lp_workgroup());
- + add_my_subnets(lp_workgroup());
-
- DEBUG(3,("Checked names\n"));
-
- + load_netbios_names();
- +
- + DEBUG(3,("Loaded names\n"));
- +
- write_browse_list();
-
- DEBUG(3,("Dumped names\n"));
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmblookup.c samba-1.9.16alpha11/source/nmblookup.c
- --- samba-1.9.16alpha10/source/nmblookup.c Sat Jun 8 15:37:54 1996
- +++ samba-1.9.16alpha11/source/nmblookup.c Thu Jul 18 20:53:16 1996
- @@ -49,7 +49,7 @@
- return False;
- }
-
- - ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
- + ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
-
- if (ServerFD == -1)
- return(False);
- @@ -93,7 +93,7 @@
- int main(int argc,char *argv[])
- {
- int opt;
- - unsigned int lookup_type = 0;
- + unsigned int lookup_type = 0x0;
- pstring lookup;
- extern int optind;
- extern char *optarg;
- @@ -164,7 +164,7 @@
- strcpy(lookup,"\01\02__MSBROWSE__\02");
- lookup_type = 1;
- } else {
- - lookup_type = 0x1d;
- + lookup_type = 0x1b;
- }
- }
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmbsync.c samba-1.9.16alpha11/source/nmbsync.c
- --- samba-1.9.16alpha10/source/nmbsync.c Mon Jun 10 15:18:57 1996
- +++ samba-1.9.16alpha11/source/nmbsync.c Mon Jul 15 17:55:05 1996
- @@ -102,6 +102,7 @@
- uint32 stype = IVAL(p,18);
- int comment_offset = IVAL(p,22) & 0xFFFF;
- char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
- +
- struct work_record *w = work;
-
- DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
- @@ -109,17 +110,17 @@
- if (stype & SV_TYPE_DOMAIN_ENUM)
- {
- /* creates workgroup on remote subnet */
- - if ((w = find_workgroupstruct(d,sname, True)))
- + if ((w = find_workgroupstruct(d,sname,True)))
- {
- if (d->my_interface)
- {
- announce_request(w, d->bcast_ip);
- }
- }
- - }
- + }
-
- - if (w)
- - add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
- + if (w)
- + add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
- }
- }
- }
- @@ -137,10 +138,11 @@
- log in on the remote server's SMB port to their IPC$ service,
- do a NetServerEnum and update our server and workgroup databases.
- ******************************************************************/
- -void sync_browse_lists(struct work_record *work, char *name, int nm_type,
- - struct in_addr ip)
- +void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- + char *name, int nm_type, struct in_addr ip)
- {
- - struct subnet_record *d;
- + if (!d || !work || !AM_MASTER(work)) return;
- +
- pid = getpid();
- uid = getuid();
- gid = getgid();
- @@ -158,8 +160,6 @@
-
- if (zero_ip(dest_ip)) return;
- have_ip = True;
- -
- - if (!(d = find_domain(ip))) return;
-
- connect_as_ipc = True;
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/printing.c samba-1.9.16alpha11/source/printing.c
- --- samba-1.9.16alpha10/source/printing.c Mon Jun 10 15:18:59 1996
- +++ samba-1.9.16alpha11/source/printing.c Sun Jun 30 15:17:26 1996
- @@ -600,10 +600,19 @@
- /****************************************************************************
- parse a lpq line for the plp printing system
- Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
- +
- +redone by tridge. Here is a sample queue:
- +
- +Local Printer 'lp2' (fjall):
- + Printing (started at Jun 15 13:33:58, attempt 1).
- + Rank Owner Pr Opt Job Host Files Size Date
- + active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
- + 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
- +
- ****************************************************************************/
- static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
- {
- - string tok[5];
- + string tok[11];
- int count=0;
-
- /* handle the case of "(standard input)" as a filename */
- @@ -611,60 +620,49 @@
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- - for (count=0; count<8 && next_token(&line,tok[count],NULL); count++) ;
- + for (count=0; count<11 && next_token(&line,tok[count],NULL); count++) ;
- +
- + /* we must get 11 tokens */
- + if (count < 11)
- + return(False);
-
- - /* we must get 5 tokens */
- - if (count < 8)
- + /* the first must be "active" or begin with an integer */
- + if (strcmp(tok[0],"active") && !isdigit(tok[0][0]))
- return(False);
-
- - /* the 4rd must be integer */
- - if (!isdigit(*tok[3])) return(False);
- + /* the 5th and 8th must be integer */
- + if (!isdigit(*tok[4]) || !isdigit(*tok[7]))
- + return(False);
-
- /* if the fname contains a space then use STDIN */
- - if (strchr(tok[3],' '))
- - strcpy(tok[3],"STDIN");
- + if (strchr(tok[6],' '))
- + strcpy(tok[6],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- - char *p = strrchr(tok[5],'/');
- + char *p = strrchr(tok[6],'/');
- if (p)
- {
- strcpy(tmp,p+1);
- - strcpy(tok[5],tmp);
- + strcpy(tok[6],tmp);
- }
- }
-
-
- - buf->job = atoi(tok[3]);
- + buf->job = atoi(tok[4]);
-
- - /* calcul de la taille du fichier */
- - if (!isdigit(*tok[7])) { buf->size = atoi(tok[7]) * 1.0 ; }
- - else {
- - string tmp;
- - strcpy(tmp,tok[7]);
- - if (strchr(tok[7],'K')) {
- - strncpy(tok[7],tmp,strlen(tmp)-1);
- - buf->size = atoi(tok[7]);
- - buf->size = buf->size * 1024;
- - }
- - if (strchr(tok[7],'M')) {
- - strncpy(tok[7],tmp,strlen(tmp)-1);
- - buf->size = atoi(tok[7]);
- - buf->size = buf->size * 1024.0 * 1000.0;
- - }
- - if (strchr(tok[7],'G')) {
- - strncpy(tok[7],tmp,strlen(tmp)-1);
- - buf->size = atoi(tok[7]);
- - buf->size = buf->size * 1024.0 * 1000000.0;
- - }
- + buf->size = atoi(tok[7]);
- + if (strchr(tok[7],'K'))
- + buf->size *= 1024;
- + if (strchr(tok[7],'M'))
- + buf->size *= 1024*1024;
-
- - }
- buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
- - StrnCpy(buf->file,tok[5],sizeof(buf->file)-1);
- + StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
- return(True);
- }
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/proto.h samba-1.9.16alpha11/source/proto.h
- --- samba-1.9.16alpha10/source/proto.h Mon Jun 10 15:18:59 1996
- +++ samba-1.9.16alpha11/source/proto.h Thu Jul 18 20:53:16 1996
- @@ -1,20 +1,39 @@
- /* This file is automatically generated with "make proto". DO NOT EDIT */
- +
- +
- +/*The following definitions come from access.c */
- +
- BOOL check_access(int snum);
- BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
- BOOL fromhost(int sock,struct from_host *f);
- +
- +/*The following definitions come from charcnv.c */
- +
- char *unix2dos_format(char *str,BOOL overwrite);
- char *dos2unix_format(char *str, BOOL overwrite);
- int interpret_character_set(char *str, int def);
- +
- +/*The following definitions come from charset.c */
- +
- void charset_initialise(void);
- void add_char_string(char *s);
- +
- +/*The following definitions come from chgpasswd.c */
- +
- BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
- BOOL chgpasswd(char *name,char *oldpass,char *newpass);
- BOOL chgpasswd(char *name,char *oldpass,char *newpass);
- +
- +/*The following definitions come from client.c */
- +
- void setup_pkt(char *outbuf);
- void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
- void cmd_help(void);
- BOOL reopen_connection(char *inbuf,char *outbuf);
- char *smb_errstr(char *inbuf);
- +
- +/*The following definitions come from clientutil.c */
- +
- void cli_setup_pkt(char *outbuf);
- BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
- int *param_len, char **data,char **param);
- @@ -29,6 +48,9 @@
- BOOL cli_open_sockets(int port);
- BOOL cli_reopen_connection(char *inbuf,char *outbuf);
- char *smb_errstr(char *inbuf);
- +
- +/*The following definitions come from clitar.c */
- +
- int strslashcmp(const char *s1, const char *s2);
- void cmd_block(void);
- void cmd_tarmode(void);
- @@ -37,6 +59,9 @@
- int process_tar(char *inbuf, char *outbuf);
- int clipfind(char **aret, int ret, char *tok);
- int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
- +
- +/*The following definitions come from dir.c */
- +
- void init_dptrs(void);
- char *dptr_path(int key);
- char *dptr_wcard(int key);
- @@ -62,8 +87,17 @@
- void DirCacheAdd(char *path,char *name,char *dname,int snum);
- char *DirCacheCheck(char *path,char *name,int snum);
- void DirCacheFlush(int snum);
- +
- +/*The following definitions come from fault.c */
- +
- void fault_setup(void (*fn)());
- +
- +/*The following definitions come from getsmbpass.c */
- +
- char *getsmbpass(char *prompt) ;
- +
- +/*The following definitions come from interface.c */
- +
- void load_interfaces(void);
- void iface_set_default(char *ip,char *bcast,char *nmask);
- BOOL ismyip(struct in_addr ip);
- @@ -73,8 +107,17 @@
- struct in_addr *iface_bcast(struct in_addr ip);
- struct in_addr *iface_nmask(struct in_addr ip);
- struct in_addr *iface_ip(struct in_addr ip);
- +
- +/*The following definitions come from ipc.c */
- +
- int reply_trans(char *inbuf,char *outbuf);
- +
- +/*The following definitions come from kanji.c */
- +
- int interpret_coding_system(char *str, int def);
- +
- +/*The following definitions come from loadparm.c */
- +
- char *lp_string(char *s);
- char *lp_logfile(void);
- char *lp_smbrun(void);
- @@ -99,6 +142,7 @@
- char *lp_logon_script(void);
- char *lp_wins_server(void);
- char *lp_interfaces(void);
- +char *lp_remote_interfaces(void);
- BOOL lp_wins_support(void);
- BOOL lp_wins_proxy(void);
- BOOL lp_domain_master(void);
- @@ -206,6 +250,9 @@
- int lp_servicenumber(char *pszServiceName);
- char *my_workgroup(void);
- char *volume_label(int snum);
- +
- +/*The following definitions come from locking.c */
- +
- BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
- int file_lock(char *name,int timeout);
- void file_unlock(int fd);
- @@ -218,6 +265,9 @@
- void del_share_mode(int fnum);
- BOOL set_share_mode(int fnum,int mode);
- void clean_share_files(void);
- +
- +/*The following definitions come from mangle.c */
- +
- int str_checksum(char *s);
- BOOL is_8_3(char *fname);
- void create_mangled_stack(int size);
- @@ -225,109 +275,217 @@
- BOOL is_mangled(char *s);
- void mangle_name_83(char *s);
- BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
- +
- +/*The following definitions come from md4.c */
- +
- +
- +/*The following definitions come from message.c */
- +
- int reply_sends(char *inbuf,char *outbuf);
- int reply_sendstrt(char *inbuf,char *outbuf);
- int reply_sendtxt(char *inbuf,char *outbuf);
- int reply_sendend(char *inbuf,char *outbuf);
- +
- +/*The following definitions come from nameannounce.c */
- +
- void announce_request(struct work_record *work, struct in_addr ip);
- void do_announce_request(char *info, char *to_name, int announce_type,
- int from,
- int to, struct in_addr dest_ip);
- +void sync_server(enum state_type state, char *serv_name, char *work_name,
- + int name_type,
- + struct in_addr ip);
- void announce_backup(void);
- +void remove_my_servers(void);
- +void announce_server(struct subnet_record *d, struct work_record *work,
- + char *name, char *comment, time_t ttl, int server_type);
- void announce_host(void);
- void announce_master(void);
- -struct work_record *remove_workgroup(struct subnet_record *d,
- - struct work_record *work);
- +
- +/*The following definitions come from namebrowse.c */
- +
- void expire_browse_cache(time_t t);
- -struct work_record *find_workgroupstruct(struct subnet_record *d,
- - fstring name, BOOL add);
- -struct subnet_record *find_domain(struct in_addr ip);
- -void dump_workgroups(void);
- -struct subnet_record *add_subnet_entry(struct in_addr source_ip,
- - struct in_addr source_mask,
- - char *name, BOOL add);
- struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- time_t ttl, struct in_addr ip);
- +void do_browser_lists(void);
- +
- +/*The following definitions come from namedbname.c */
- +
- +BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
- +BOOL ms_browser_name(char *name, int type);
- +void remove_name(struct subnet_record *d, struct name_record *n);
- +struct name_record *find_name(struct name_record *n,
- + struct nmb_name *name,
- + int search);
- +struct name_record *find_name_search(struct subnet_record **d,
- + struct nmb_name *name,
- + int search, struct in_addr ip);
- +void dump_names(void);
- +void load_netbios_names(void);
- +void remove_netbios_name(struct subnet_record *d,
- + char *name,int type, enum name_source source,
- + struct in_addr ip);
- +struct name_record *add_netbios_entry(struct subnet_record *d,
- + char *name, int type, int nb_flags,
- + int ttl, enum name_source source, struct in_addr ip,
- + BOOL new_only,BOOL wins);
- +void expire_names(time_t t);
- +struct name_record *search_for_name(struct subnet_record **d,
- + struct nmb_name *question,
- + struct in_addr ip, int Time, int search);
- +
- +/*The following definitions come from namedbresp.c */
- +
- +void add_response_record(struct subnet_record *d,
- + struct response_record *n);
- +void remove_response_record(struct subnet_record *d,
- + struct response_record *n);
- +struct response_record *make_response_queue_record(enum state_type state,
- + int id,uint16 fd,
- + int quest_type, char *name,int type, int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip);
- +struct response_record *find_response_record(struct subnet_record **d,
- + uint16 id);
- +
- +/*The following definitions come from namedbserver.c */
- +
- +void remove_old_servers(struct work_record *work, time_t t,
- + BOOL remove_all);
- +struct server_record *find_server(struct work_record *work, char *name);
- struct server_record *add_server_entry(struct subnet_record *d,
- struct work_record *work,
- char *name,int servertype,
- int ttl,char *comment,
- BOOL replace);
- -void write_browse_list(void);
- void expire_servers(time_t t);
- +
- +/*The following definitions come from namedbsubnet.c */
- +
- +struct subnet_record *find_subnet(struct in_addr bcast_ip);
- +struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
- +void add_subnet_interfaces(void);
- +void add_my_subnets(char *group);
- +struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
- + struct in_addr mask_ip,
- + char *name, BOOL add, BOOL lmhosts);
- +void write_browse_list(void);
- +
- +/*The following definitions come from namedbwork.c */
- +
- +struct work_record *remove_workgroup(struct subnet_record *d,
- + struct work_record *work,
- + BOOL remove_all_servers);
- +struct work_record *find_workgroupstruct(struct subnet_record *d,
- + fstring name, BOOL add);
- +void dump_workgroups(void);
- +
- +/*The following definitions come from nameelect.c */
- +
- void check_master_browser(void);
- void browser_gone(char *work_name, struct in_addr ip);
- void send_election(struct subnet_record *d, char *group,uint32 criterion,
- int timeup,char *name);
- -void become_nonmaster(struct subnet_record *d, struct work_record *work);
- +void name_unregister_work(struct subnet_record *d, char *name, int name_type);
- +void name_register_work(struct subnet_record *d, char *name, int name_type,
- + int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
- +void become_master(struct subnet_record *d, struct work_record *work);
- +void become_nonmaster(struct subnet_record *d, struct work_record *work,
- + int remove_type);
- void run_elections(void);
- void process_election(struct packet_struct *p,char *buf);
- BOOL check_elections(void);
- -BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- - struct in_addr to_ip,char *master,char *rname,
- - void (*fn)());
- -BOOL name_query(int fd,char *name,int name_type,
- - BOOL bcast,BOOL recurse,
- - struct in_addr to_ip, struct in_addr *ip,void (*fn)());
- -void expire_netbios_response_entries(time_t t);
- -void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,
- - int opcode,BOOL recurse,struct nmb_name *rr_name,
- - int rr_type,int rr_class,int ttl,char *data,int len);
- -uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
- - int nb_flags,BOOL bcast,BOOL recurse,
- - struct in_addr to_ip);
- -void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
- - char *name,int name_type,int nb_flags,
- - BOOL bcast,BOOL recurse,struct in_addr to_ip);
- -void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
- - int name_type,int nb_flags,BOOL bcast,BOOL recurse,
- - struct in_addr to_ip);
- -struct name_response_record *find_name_query(uint16 id);
- +
- +/*The following definitions come from namelogon.c */
- +
- +void process_logon_packet(struct packet_struct *p,char *buf,int len);
- +
- +/*The following definitions come from namepacket.c */
- +
- +void debug_browse_data(char *outbuf, int len);
- +void initiate_netbios_packet(uint16 *id,
- + int fd,int quest_type,char *name,int name_type,
- + int nb_flags,BOOL bcast,BOOL recurse,
- + struct in_addr to_ip);
- +void reply_netbios_packet(struct packet_struct *p1,int trn_id,
- + int rcode, int rcv_code, int opcode, BOOL recurse,
- + struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
- + char *data,int len);
- void queue_packet(struct packet_struct *packet);
- void run_packet_queue();
- void listen_for_packets(BOOL run_election);
- -BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
- - char *serv_name, struct in_addr ip);
- BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
- char *dstname,int src_type,int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip);
- -void remove_name(struct name_record *n);
- -void dump_names(void);
- -void remove_netbios_name(char *name,int type, enum name_source source,
- - struct in_addr ip);
- -struct name_record *add_netbios_entry(char *name, int type, int nb_flags,
- - int ttl,
- - enum name_source source,
- - struct in_addr ip,
- - BOOL new_only);
- -void remove_name_entry(char *name,int type);
- -void add_name_entry(char *name,int type,int nb_flags);
- +
- +/*The following definitions come from namequery.c */
- +
- +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- + struct in_addr to_ip,char *master,char *rname,
- + void (*fn)());
- +BOOL name_query(int fd,char *name,int name_type,
- + BOOL bcast,BOOL recurse,
- + struct in_addr to_ip, struct in_addr *ip,void (*fn)());
- +
- +/*The following definitions come from nameresp.c */
- +
- +void expire_netbios_response_entries();
- +struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
- + int fd,int quest_type,enum state_type state,
- + char *name,int name_type,int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip);
- +struct response_record *queue_netbios_packet(struct subnet_record *d,
- + int fd,int quest_type,enum state_type state,char *name,
- + int name_type,int nb_flags, time_t ttl,
- + BOOL bcast,BOOL recurse,
- + struct in_addr send_ip, struct in_addr reply_to_ip);
- +
- +/*The following definitions come from nameserv.c */
- +
- +void remove_name_entry(struct subnet_record *d, char *name,int type);
- +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
- void add_my_names(void);
- void remove_my_names();
- void refresh_my_names(time_t t);
- -void expire_names(time_t t);
- -void response_name_release(struct packet_struct *p);
- +void query_refresh_names(void);
- +
- +/*The following definitions come from nameservreply.c */
- +
- +void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
- + uint16 response_id,
- + struct nmb_name *name,
- + int nb_flags, int ttl, struct in_addr register_ip,
- + BOOL new_owner, struct in_addr reply_to_ip);
- +void send_name_response(int fd, struct in_addr from_ip,
- + int name_trn_id, int opcode, BOOL success, BOOL recurse,
- + struct nmb_name *reply_name, int nb_flags, int ttl,
- + struct in_addr ip);
- void reply_name_release(struct packet_struct *p);
- -void response_name_reg(struct packet_struct *p);
- void reply_name_reg(struct packet_struct *p);
- void reply_name_status(struct packet_struct *p);
- void reply_name_query(struct packet_struct *p);
- -void process_nmb(struct packet_struct *p);
- +
- +/*The following definitions come from nameservresp.c */
- +
- +void debug_state_type(int state);
- +void response_netbios_packet(struct packet_struct *p);
- +
- +/*The following definitions come from namework.c */
- +
- void reset_server(char *name, int state, struct in_addr ip);
- void tell_become_backup(void);
- -void do_browser_lists(void);
- -void sync_server(enum cmd_type cmd, char *serv_name, char *work_name,
- - int name_type,
- - struct in_addr ip);
- -void update_from_reg(char *name, int type, struct in_addr ip);
- -void add_my_domains(char *group);
- BOOL same_context(struct dgram_packet *dgram);
- BOOL listening_name(struct work_record *work, struct nmb_name *n);
- -void process_logon_packet(struct packet_struct *p,char *buf,int len);
- BOOL listening_type(struct packet_struct *p, int command);
- void process_browse_packet(struct packet_struct *p,char *buf,int len);
- -void process_dgram(struct packet_struct *p);
- +
- +/*The following definitions come from nmbd.c */
- +
- BOOL reload_services(BOOL test);
- +
- +/*The following definitions come from nmblib.c */
- +
- void debug_nmb_packet(struct packet_struct *p);
- char *namestr(struct nmb_name *n);
- void free_nmb_packet(struct nmb_packet *nmb);
- @@ -336,11 +494,23 @@
- void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
- BOOL send_packet(struct packet_struct *p);
- struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
- +
- +/*The following definitions come from nmblookup.c */
- +
- int main(int argc,char *argv[]);
- +
- +/*The following definitions come from nmbsync.c */
- +
- char *getsmbpass(char *pass);
- -void sync_browse_lists(struct work_record *work, char *name, int nm_type,
- - struct in_addr ip);
- +void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- + char *name, int nm_type, struct in_addr ip);
- +
- +/*The following definitions come from params.c */
- +
- BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
- +
- +/*The following definitions come from password.c */
- +
- void generate_next_challenge(char *challenge);
- BOOL set_challenge(char *challenge);
- BOOL last_challenge(char *challenge);
- @@ -360,21 +530,36 @@
- BOOL check_hosts_equiv(char *user);
- BOOL server_cryptkey(char *buf);
- BOOL server_validate(char *buf);
- +
- +/*The following definitions come from pcap.c */
- +
- BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
- void pcap_printer_fn(void (*fn)());
- +
- +/*The following definitions come from predict.c */
- +
- int read_predict(int fd,int offset,char *buf,char **ptr,int num);
- void do_read_prediction();
- void invalidate_read_prediction(int fd);
- +
- +/*The following definitions come from printing.c */
- +
- void lpq_reset(int snum);
- void print_file(int fnum);
- int get_printqueue(int snum,int cnum,print_queue_struct **queue,
- print_status_struct *status);
- void del_printqueue(int cnum,int snum,int jobid);
- void status_printjob(int cnum,int snum,int jobid,int status);
- +
- +/*The following definitions come from quotas.c */
- +
- BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
- BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
- BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
- BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
- +
- +/*The following definitions come from replace.c */
- +
- char *Strstr(char *s, char *p);
- time_t Mktime(struct tm *t);
- int InNetGr(char *group,char *host,char *user,char *dom);
- @@ -382,6 +567,9 @@
- void *realloc_wrapped(void *ptr,int size,char *file,int line);
- void free_wrapped(void *ptr,char *file,int line);
- void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
- +
- +/*The following definitions come from reply.c */
- +
- int reply_special(char *inbuf,char *outbuf);
- int reply_tcon(char *inbuf,char *outbuf);
- int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
- @@ -432,6 +620,9 @@
- int reply_writebs(char *inbuf,char *outbuf);
- int reply_setattrE(char *inbuf,char *outbuf);
- int reply_getattrE(char *inbuf,char *outbuf);
- +
- +/*The following definitions come from server.c */
- +
- mode_t unix_mode(int cnum,int dosmode);
- int dos_mode(int cnum,char *path,struct stat *sbuf);
- int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
- @@ -473,6 +664,9 @@
- char *smb_fn_name(int type);
- int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
- int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
- +
- +/*The following definitions come from smbencrypt.c */
- +
- void str_to_key(uchar *str,uchar *key);
- void D1(uchar *k, uchar *d, uchar *out);
- void E1(uchar *k, uchar *d, uchar *out);
- @@ -481,10 +675,26 @@
- void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
- void E_md4hash(uchar *passwd, uchar *p16);
- void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
- +
- +/*The following definitions come from smbpass.c */
- +
- +struct smb_passwd *get_smbpwnam(char *name);
- +
- +/*The following definitions come from smbpasswd.c */
- +
- +
- +/*The following definitions come from smbrun.c */
- +
- +
- +/*The following definitions come from status.c */
- +
- void Ucrit_addUsername(pstring username);
- unsigned int Ucrit_checkUsername(pstring username);
- void Ucrit_addPid(int pid);
- unsigned int Ucrit_checkPid(int pid);
- +
- +/*The following definitions come from system.c */
- +
- int sys_select(fd_set *fds,struct timeval *tval);
- int sys_select(fd_set *fds,struct timeval *tval);
- int sys_unlink(char *fname);
- @@ -499,7 +709,16 @@
- int sys_rename(char *from, char *to);
- int sys_chown(char *fname,int uid,int gid);
- int sys_chroot(char *dname);
- +
- +/*The following definitions come from testparm.c */
- +
- +
- +/*The following definitions come from testprns.c */
- +
- int main(int argc, char *argv[]);
- +
- +/*The following definitions come from time.c */
- +
- void GetTimeOfDay(struct timeval *tval);
- void TimeInit(void);
- int TimeDiff(time_t t);
- @@ -514,20 +733,35 @@
- time_t make_unix_date3(void *date_ptr);
- BOOL set_filetime(char *fname,time_t mtime);
- char *timestring(void );
- +
- +/*The following definitions come from trans2.c */
- +
- int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
- int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
- int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
- int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
- +
- +/*The following definitions come from ufc.c */
- +
- char *ufc_crypt(char *key,char *salt);
- +
- +/*The following definitions come from uid.c */
- +
- void init_uid(void);
- BOOL become_guest(void);
- BOOL become_user(int cnum, int uid);
- BOOL unbecome_user(void );
- int smbrun(char *cmd,char *outfile);
- +
- +/*The following definitions come from username.c */
- +
- char *get_home_dir(char *user);
- void map_username(char *user);
- struct passwd *Get_Pwnam(char *user,BOOL allow_change);
- BOOL user_in_list(char *user,char *list);
- +
- +/*The following definitions come from util.c */
- +
- void setup_logging(char *pname,BOOL interactive);
- void reopen_logs(void);
- BOOL is_a_socket(int fd);
- @@ -634,6 +868,9 @@
- void BlockSignals(BOOL block);
- void ajt_panic(void);
- char *readdirname(void *p);
- +
- +/*The following definitions come from vt_mode.c */
- +
- int VT_Check(char *buffer);
- int VT_Start_utmp(void);
- int VT_Stop_utmp(void);
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/reply.c samba-1.9.16alpha11/source/reply.c
- --- samba-1.9.16alpha10/source/reply.c Mon Jun 10 15:19:00 1996
- +++ samba-1.9.16alpha11/source/reply.c Mon Jul 15 17:55:06 1996
- @@ -2062,6 +2062,11 @@
- cnum = SVAL(inbuf,smb_tid);
- uid = SVAL(inbuf,smb_uid);
-
- + if (!OPEN_CNUM(cnum)) {
- + DEBUG(4,("Invalid cnum in tdis (%d)\n",cnum));
- + return(ERROR(ERRSRV,ERRinvnid));
- + }
- +
- Connections[cnum].used = False;
-
- close_cnum(cnum,uid);
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smb.h samba-1.9.16alpha11/source/smb.h
- --- samba-1.9.16alpha10/source/smb.h Mon Jun 10 15:19:02 1996
- +++ samba-1.9.16alpha11/source/smb.h Thu Jul 18 20:53:16 1996
- @@ -108,10 +108,16 @@
- #else
- EXTERN int syslog_level;
-
- -#define DEBUG(level,body) ((DEBUGLEVEL>=(level))? \
- - (syslog_level = (level), Debug1 body):0)
- +#define DEBUG(level,body) ((DEBUGLEVEL>=(level))? (syslog_level = (level), Debug1 body):0)
- #endif
-
- +/* this defines the error codes that receive_smb can put in smberrcode */
- +#define SMBERR_OK 0
- +#define SMBERR_TIMEOUT 1
- +#define SMBERR_EOF 2
- +#define SMBERR_ERROR 3
- +
- +
- #define DIR_STRUCT_SIZE 43
-
- /* these define all the command types recognised by the server - there
- @@ -380,6 +386,15 @@
- BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
- };
-
- +
- +/* used for network interfaces */
- +struct interface
- +{
- + struct interface *next;
- + struct in_addr ip;
- + struct in_addr bcast;
- + struct in_addr nmask;
- +};
-
- /* this is used for smbstatus */
- struct connect_record
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smbpass.c samba-1.9.16alpha11/source/smbpass.c
- --- samba-1.9.16alpha10/source/smbpass.c Mon Jun 10 15:19:02 1996
- +++ samba-1.9.16alpha11/source/smbpass.c Thu Jul 18 20:53:16 1996
- @@ -109,8 +109,7 @@
- /*
- * Routine to search the smbpasswd file for an entry matching the username.
- */
- -struct smb_passwd *
- -get_smbpwnam(char *name)
- +struct smb_passwd *get_smbpwnam(char *name)
- {
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smbtar samba-1.9.16alpha11/source/smbtar
- --- samba-1.9.16alpha10/source/smbtar Sat May 4 17:50:25 1996
- +++ samba-1.9.16alpha11/source/smbtar Sun Jun 30 15:17:26 1996
- @@ -138,4 +138,3 @@
- -E -N $log -D "'$cdcmd'" \
- -T${tarcmd}${tarargs} $blocksize $newer $tapefile $* $verbose
-
- -
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/system.c samba-1.9.16alpha11/source/system.c
- --- samba-1.9.16alpha10/source/system.c Sun May 5 17:18:39 1996
- +++ samba-1.9.16alpha11/source/system.c Sun Jun 30 15:17:26 1996
- @@ -25,13 +25,17 @@
-
- /*
- The idea is that this file will eventually have wrappers around all
- - important system calls in samba. The aim is twofold:
- + important system calls in samba. The aims are:
-
- - to enable easier porting by putting OS dependent stuff in here
-
- - to allow for hooks into other "pseudo-filesystems"
-
- - to allow easier integration of things like the japanese extensions
- +
- + - to support the philosophy of Samba to expose the features of
- + the OS within the SMB model. In general whatever file/printer/variable
- + expansions/etc make sense to the OS should be acceptable to Samba.
- */
-
-
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallbin.sh samba-1.9.16alpha11/source/uninstallbin.sh
- --- samba-1.9.16alpha10/source/uninstallbin.sh Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/uninstallbin.sh Fri Jul 5 13:53:11 1996
- @@ -0,0 +1,43 @@
- +#!/bin/sh
- +#4 July 96 Dan.Shearer@UniSA.edu.au
- +
- +INSTALLPERMS=$1
- +BASEDIR=$2
- +BINDIR=$3
- +LIBDIR=$4
- +VARDIR=$5
- +shift
- +shift
- +shift
- +shift
- +shift
- +
- +if [ ! -d $BINDIR ]; then
- + echo Directory $BINDIR does not exist!
- + echo Do a "make installbin" or "make install" first.
- + exit 1
- +fi
- +
- +for p in $*; do
- + if [ ! -f $BINDIR/$p ]; then
- + echo $BINDIR/$p does not exist!
- + else
- + echo Removing $BINDIR/$p
- + rm -f $BINDIR/$p
- + if [ -f $BINDIR/$p ]; then
- + echo Cannot remove $BINDIR/$p... does $USER have privileges?
- + fi
- + fi
- +done
- +
- +
- +cat << EOF
- +======================================================================
- +The binaries have been uninstalled. You may restore the binaries using
- +the command "make installbin" or "make install" to install binaries,
- +man pages and shell scripts. You can restore a previous version of the
- +binaries (if there were any) using "make revert".
- +======================================================================
- +EOF
- +
- +exit 0
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallman.sh samba-1.9.16alpha11/source/uninstallman.sh
- --- samba-1.9.16alpha10/source/uninstallman.sh Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/uninstallman.sh Fri Jul 5 13:53:11 1996
- @@ -0,0 +1,31 @@
- +#!/bin/sh
- +#4 July 96 Dan.Shearer@UniSA.edu.au
- +
- +MANDIR=$1
- +SRCDIR=$2
- +
- +echo Uninstalling man pages from $MANDIR
- +
- +for sect in 1 5 7 8 ; do
- + for m in $MANDIR/man$sect ; do
- + for s in $SRCDIR../docs/*$sect; do
- + FNAME=$m/`basename $s`
- + if test -f $FNAME; then
- + echo Deleting $FNAME
- + rm -f $FNAME
- + test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?
- + else
- + echo $FNAME does not exist! Check defines in the Makefile
- + fi
- + done
- + done
- +done
- +
- +cat << EOF
- +======================================================================
- +The man pages have been uninstalled. You may install them again using
- +the command "make installman" or make "install" to install binaries,
- +man pages and shell scripts.
- +======================================================================
- +EOF
- +exit 0
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallscripts.sh samba-1.9.16alpha11/source/uninstallscripts.sh
- --- samba-1.9.16alpha10/source/uninstallscripts.sh Thu Jan 1 10:00:00 1970
- +++ samba-1.9.16alpha11/source/uninstallscripts.sh Fri Jul 5 13:53:12 1996
- @@ -0,0 +1,37 @@
- +#!/bin/sh
- +# 5 July 96 Dan.Shearer@UniSA.Edu.Au - almost identical to uninstallbin.sh
- +
- +INSTALLPERMS=$1
- +BINDIR=$2
- +
- +shift
- +shift
- +
- +if [ ! -d $BINDIR ]; then
- + echo Directory $BINDIR does not exist!
- + echo Do a "make installscripts" or "make install" first.
- + exit 1
- +fi
- +
- +for p in $*; do
- + if [ ! -f $BINDIR/$p ]; then
- + echo $BINDIR/$p does not exist!
- + else
- + echo Removing $BINDIR/$p
- + rm -f $BINDIR/$p
- + if [ -f $BINDIR/$p ]; then
- + echo Cannot remove $BINDIR/$p... does $USER have privileges?
- + fi
- + fi
- +done
- +
- +cat << EOF
- +======================================================================
- +The scripts have been uninstalled. You may reinstall them using
- +the command "make installscripts" or "make install" to install binaries,
- +man pages and shell scripts. You may recover a previous version (if any
- +with "make revert".
- +======================================================================
- +EOF
- +
- +exit 0
- diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/version.h samba-1.9.16alpha11/source/version.h
- --- samba-1.9.16alpha10/source/version.h Mon Jun 10 15:19:48 1996
- +++ samba-1.9.16alpha11/source/version.h Thu Jul 18 20:53:51 1996
- @@ -1 +1 @@
- -#define VERSION "1.9.16alpha10"
- +#define VERSION "1.9.16alpha11"
-